Java适配Node.js中AES-CBC-ZeroPadding加密

3,926 阅读1分钟

背景

在开发中,移动端(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方式填充即可。