说明:
RSA为非对称加密,用于加密和解密,分为公钥和私钥。例如:app发起支付时,使用公钥对订单串进行加密,然后将加密订单串传给服务器,服务器使用私钥进行解密,验证数据的真实性。
使用:
public class RSAUtil {
private static final String algorithm = "RSA";
private static final String signature_algorithm = "MD5withRSA";
private static final String KEY_PUBLIC = "PublicKey";
private static final String KEY_PRIVATE = "PrivateKey";
/**
* 生成公钥串、私钥串
*
* @return Base64编码过的公钥串、Base64编码过的私钥串
*/
public static Map<String, String> generatorKey() {
Map<String, String> map = new HashMap<String, String>();
try {
KeyPairGenerator keygen = KeyPairGenerator.getInstance(algorithm);
// 创建随机产生器
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed("abcdefg".getBytes());
keygen.initialize(1024, secureRandom);
KeyPair keys = keygen.genKeyPair();
// 生成公钥
RSAPublicKey publicKey = (RSAPublicKey) keys.getPublic();
map.put(KEY_PUBLIC, Base64.encode(publicKey.getEncoded()));
// 生成私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keys.getPrivate();
map.put(KEY_PRIVATE, Base64.encode(privateKey.getEncoded()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return map;
}
/**
* 用私钥对订单串进行加密
*
* @param orderInfo 未加密订单原串
* @param privateKey Base64编码过的私钥串
*
* @return Base64编码过的已加密订单串
*/
public static String encrypt(String orderInfo, String privateKeyStr) {
try {
// 根据私钥byte[]创建PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
// 指定RSA加密算法
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 取得私钥对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对订单串加密并Base64编码
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, priKey);
return Base64.encode(cipher.doFinal(orderInfo.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 用公钥对订单串进行解密
*
* @param orderInfo Base64编码过的已加密订单串
* @param publicKey Base64编码过的公钥串
* @param sign Base64编码过的签名串
*
* @return 解密后的订单原串
*/
public static String decrypt(String orderInfo, String publicKeyStr) {
try {
// 根据公钥byte[]创建X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyStr));
// 指定RSA加密算法
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 取公钥对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 对订单串解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return new String(cipher.doFinal(Base64.decode(orderInfo)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使用私钥对订单串进行签名
*
* @param orderInfo 未加密订单串
* @param privateKey Base64编码过的私钥串
*
* @return Base64编码过的签名串
*/
public static String generatorSign(String orderInfo, String privateKey) {
try {
// 根据私钥byte[]创建PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
// 指定RSA加密算法
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 取得私钥对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对订单串进行签名
Signature signature = Signature.getInstance(signature_algorithm);
signature.initSign(priKey);
signature.update(orderInfo.getBytes());
// 对私钥进行Base64编码
return Base64.encode(signature.sign());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使用公钥校验签名
*
* @param orderInfo 未加密订单串
* @param publicKey Base64编码过的公钥串
* @param sign Base64编码过的签名串
*
* @return 校验成功返回true, 校验失败返回false
*/
public static boolean verifySign(String orderInfo, String publicKey, String sign) {
try {
// 根据公钥byte[]创建X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
// 指定RSA加密算法
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 取公钥对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 根据公钥和待加密串初始化Signature
Signature signature = Signature.getInstance(signature_algorithm);
signature.initVerify(pubKey);
signature.update(orderInfo.getBytes());
// 根据公钥和订单串进行签名校验,通过表示正常,否则表示订单串是伪造的。
return signature.verify(Base64.decode(sign));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void main(String[] args) {
// // 产生公钥和私钥,保存起来下次使用
// Map<String, String> keyMap = generatorKey();
// // 获得公钥
// String publicKey = keyMap.get(KEY_PUBLIC);
// // 获得私钥
// String privateKey = keyMap.get(KEY_PRIVATE);
// System.err.println("公钥 : " + publicKey);
// System.err.println("私钥 : " + privateKey);
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIb7h8RwIyvjF1bZPBid2W0ZSn3WXRTYJ4BW6niL1IZhlQVupFEyjFS1mpk6gU9g7InlZ350A/H9DWiX5hxOWunETecFTP5XfqbvyUTR5N6WErhdSkinrVFAaQSQOxn5ID8GhXg+iTsPzidAFAJ5sKIJ9OgwOL6d1ABrbBPydlMdAgMBAAECgYBvdRS3VK0GGR71fK0N2pFlb6O94pq7knyTkbFMVpHnYH4vnRubXHTZoZcFfXS2+d53QvDBTsTPNVe0DPFaYCzacNEvVYXiIg2tNM/3EmD/Zy8yn2ywmkcuA88upTOLftceJ8H7FQOFhxqwyAOMsn46MmnkFkfidDtEl3qOgm4uNQJBANy331/8gsRBUDMA//FlJXvFUaWY/hsrPltfHMUfMaMZi2z0nbTZ9q/hUXWOCZvS+QJsaKNx8qfWBftgkulQNz8CQQCcjzjCy3yEULR2vAk9lET1lH/UZ/1Jq2d9Dsaf+Bt5BBmHAvLZR6wiWYly8pqR8Zn7ncFnmmVcll45CnCQSVqjAkEAz3WE4BPYVd+OImKuL5eCw/OT6rMDJUZgNkIQKLhJT6STCLZkBblZxbdjebsoDO8gXsbHE9nm2xqwRLdhXyumwQJARZ+n1XEbAdjGOJts3JbIiBIvOu24BYAVeNcOW+vBg/Lfy1vzVc967Je2+YiMVuUD3pMMhJ9z/lXcty8+WdxVUwJASJgBFbNqoycbPByWW9sxuDwYBmZxr2+UCVnp/AynNGS3r/gTTIgbVIOEdEk1nHDbwXthxY4P5WAUGZm4KJNY5g==";
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG+4fEcCMr4xdW2TwYndltGUp91l0U2CeAVup4i9SGYZUFbqRRMoxUtZqZOoFPYOyJ5Wd+dAPx/Q1ol+YcTlrpxE3nBUz+V36m78lE0eTelhK4XUpIp61RQGkEkDsZ+SA/BoV4Pok7D84nQBQCebCiCfToMDi+ndQAa2wT8nZTHQIDAQAB";
// 待签名的订单串
String orderInfo = "orderId=1001&price=10.1&desc=书本&num=1";
// 加密订单串
String encryptOrderInfo = encrypt(orderInfo, privateKey);
System.err.println("加密后的订单串: " + encryptOrderInfo);
// 解密订单串
String decryptOrderInfo = decrypt(encryptOrderInfo, publicKey);
System.err.println("解密后的订单串: " + decryptOrderInfo);
// 使用私钥对订单串进行签名
String sign = generatorSign(orderInfo, privateKey);
System.err.println("签名 : " + sign);
// 使用公钥校验签名
boolean result = verifySign(orderInfo, publicKey, sign);
System.err.println("签名校验结果: " + result);
}
}