首页 > 解决方案 > Javascript 到 Java AES

问题描述

我需要将加密字符串从 Javascript 发送到 Android,但出现以下错误:javax.crypto.BadPaddingException: pad block损坏

不幸的是,我无法修改 Android 实现,我只能调整 Javascript 代码。我已经尝试过 CryptoJS 和现在的 aes-js。

安卓解密代码:

        SecretKey secret_user_key = new SecretKeySpec(user_key, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secret_user_key);

        byte[] clearBytes = cipher.doFinal(encrypted);

Javascript加密:

        var aesCbc = new aesjs.ModeOfOperation.cbc(new Uint8Array(userKey));
        var encrypted = aesCbc.encrypt(aesjs.padding.pkcs7.pad(clearByteArray));

用户密钥和加密变量在两个平台上都是相同的。user key 和 clearByteArray 都是 32 字节。

请注意,Android 实现没有指定填充、iv 或操作模式,但我无法修改那部分。

我已经尝试了十亿种不同的加密参数组合,并为此浪费了无数小时。

编辑:这也是我必须在 Javascript 上重现的 Android 上的等效加密方法:

        SecretKey secret_user_key = new SecretKeySpec(user_key, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secret_user_key);
        byte[] encrypted = cipher.doFinal(clearBytes);

        return encrypted;

标签: javascriptjavaandroidencryptionaes

解决方案


Android中使用的模式Cipher.getInstance("AES");是ECB模式。欧洲央行模式不安全。您可以从Wikipedia上的企鹅图像中看到它。您应该至少使用 CBC 模式或更好的身份验证加密作为 AES-GCM 模式。

既然您说您不能更改 Android 部分,那么您必须将 JS 部分降级为 ECB 模式。

var aesEcb = new aesjs.ModeOfOperation.ecb(key);

推荐阅读