需求&实现思路
工作中遇到一个需求,需要将接口数据加密发送给后台,项目中采用RSA+AES方式,记录一下思路和实现。
一、加密
1、随机生成AES 32位密钥
2、通过AES对传递数据加密
3、通过RSA的公钥Publickey对AES的密钥进行加密
4、通过RSA的私钥Privatekey对数据进行签名
二、解密
1、得到数据拿到sign值,先做验签
2、使用RSA的私钥private_key解密拿到AES的aesKey
3、使用AES解密得到所需数据
下面是具体实现步骤
1、通过opensll生成加解密所需要的公钥和私钥,生成步骤自行百度,这里 不在介绍
2、AES加解密
public static class AESUtils {
private static final String AES = "AES";
//偏移量
private static final String IV_STRING = "";
/**
* 密钥长度32字节,256位
*/
private static final int AES_KEY_LENGTH = 32;
/**
* 随机生成32位AES密钥
*/
public static String getRandomString() {
//生成规则自己定义
String base = "";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < AES_KEY_LENGTH; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 加密
*
* @param content 加密内容
* @return 密文
* @throws Exception e
*/
@RequiresApi(api = Build.VERSION_CODES.O)
public static String encrypt(String key, String content) throws Exception {
byte[] encryptedBytes = new byte[0];
try {
byte[] byteContent = content.getBytes();
// 注意,为了能与 iOS 统一
// 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
byte[] enCodeFormat = key.getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, AES);
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
// 指定加密的算法、工作模式和填充方式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
encryptedBytes = cipher.doFinal(byteContent);
// 同样对加密后数据进行 base64 编码
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
LogUtil.e("AES decrypt Exception,content = {},Exception = {}" + content + Arrays.toString(e.getStackTrace()));
}
// return Base64.getUrlEncoder().encodeToString(encryptedBytes);
return Base64Util.encode(encryptedBytes);
}
/**
* 解密
*
* @param content 密文
* @return 明文
* @throws Exception e
*/
@RequiresApi(api = Build.VERSION_CODES.O)
public static String decrypt(String content, String aesKey) {
// base64 解码
try {
byte[] encryptedBytes = Base64Util.decode(content);
byte[] enCodeFormat = aesKey.getBytes();
SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, AES);
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] result = cipher.doFinal(encryptedBytes