如何使用与 Coldfusion 加密相同的 Android AES 加密

Nav*_*mar 2 java encryption coldfusion android aes

我们在网络上使用coldfusion 加密方法。

Encrypt(plainText, key, "AES", "Hex")
Run Code Online (Sandbox Code Playgroud)

并且Android我们以以下方式使用加密方法:

public static String aesEncryption(String plainText, String key) {
        try {
            SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher aesCipher = Cipher.getInstance("AES");
            aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
            aesCipher.update(plainText.getBytes());
            byte[] cipherText = aesCipher.doFinal();
            return bytesToHex(cipherText);
        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }


    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }
Run Code Online (Sandbox Code Playgroud)

但是在Android加密的输出中不匹配,如何使用与AndroidAES 相同的加密coldfusion encrypt

Top*_*aco 5

当指定为 algorithm [1]时,Coldfusion默认encrypt使用AES/ECB/PKCS5填充。在 Java/Android 中,如果仅指定[2],则提供程序决定使用哪种模式和填充,但通常它也是填充(如在我的机器上,Android 9,API 28)。因此,算法的规范可能不是原因。尽管如此,最好在 Java 代码中使用完整规范而不是.AESAESAES/ECB/PKCS5AES/ECB/PKCS5PaddingAES

可能是在 Java 代码中错误地使用了来自 Coldfusion 代码的密钥。在 Coldfusion 中,密钥通常是用generateSecretKey [3]生成的,它返回 Base64 编码的密钥。这意味着在 Android 代码中,密钥首先必须使用 Base64 解码:

SecretKey secKey = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");
Run Code Online (Sandbox Code Playgroud)

此外,如果密钥是为 AES-128 生成的,则不会抛出异常,因为密钥长 16 个字节,而 Base64 编码仅为 24 个字节,这在当前的 Android 代码中会生成相同长度的 AES 密钥,因为

SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES"); 
Run Code Online (Sandbox Code Playgroud)

因此,将使用 AES-192 而不是 AES-128,当然会产生不同的密文。

更新:正如评论中已经提到的,ECB 是一种不安全的操作模式,不应使用[4]。一个更安全的替代方案是 CBC [5],它在 Java/Android 和 Coldfusion [6]中都受支持。更安全、更现代的是 GCM,这是一种经过身份验证的加密算法,可保证数据的真实性和机密性[7],如果支持,则应首选。这里可以找到更多模式的描述[8]

  • “可能是密钥使用不正确”这很可能是造成差异的原因。尝试将密钥解码为 base64,它可能会起作用。一旦它起作用,另请参阅[使用 CBC 而不是默认 ECB](/sf/answers/4165010181/) 的其他建议。 (4认同)
  • 没有建议不要使用欧洲央行吗? (2认同)