背景
在开发中,移动端(Android)和平台端共用一个登录接口。在加密方式上,平台端使用了AES/CBC/ZeroPadding加密方式,Java虽然支持AES的CBC模式,但是填充方式不支持ZeroPadding。于是简单了解了下AES加密,用Java实现ZeroPadding填充模式。
Node.js上的加密
这是平台端给我的他们的加密方式:
const key = CryptoJS.enc.Latin1.parse('加密密钥');
const iv = key;
const uid = CryptoJS.AES.encrypt(params.uid, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding,
});
Java端实现
/**
* 适配Node.js中AES-CBC-ZeroPadding加密
*
* @param sSrc -- 待加密内容
* @param encodingFormat -- 字符串编码方式
* @param sKey -- 加密密钥
* @param ivParameter -- 偏移量
* @return Base64编码后的字符串,"":编码出错
*/
public static String aesEncrypt(String sSrc, String encodingFormat, String sKey, String ivParameter) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,
new SecretKeySpec(sKey.getBytes(encodingFormat), "AES"),
new IvParameterSpec(ivParameter.getBytes(encodingFormat)));
int blockSize = cipher.getBlockSize();
//用'\0'填充长度至整数倍,对应node.js中ZeroPadding
StringBuilder dataBuilder = new StringBuilder(sSrc);
if (sSrc.length() % blockSize != 0) {
for (int i = 0; i<blockSize-(sSrc.length() % blockSize); i++){
dataBuilder.append("\0");
}
}
byte[] encrypted = cipher.doFinal(dataBuilder.toString().getBytes(encodingFormat));
return Base64.encodeToString(encrypted,0).trim();
}catch (Exception e){
return "";
}
}
总结
ZeroPadding就是用'\0'将加密内容填充至BlockSize(CBC一般是16)的整数倍,再用NoPadding方式填充即可。