簡體   English   中英

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

[英]How to use Android AES encryption same as coldfusion encrypt

我們在網絡上使用coldfusion 加密方法。

Encrypt(plainText, key, "AES", "Hex")

Android我們通過以下方式使用 encrypt 方法:

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);
    }

但是在Android中加密的輸出不匹配,如何使用與coldfusion encrypt相同的Android AES加密?

AES指定為算法[1]時,Coldfusion 的encrypt默認使用AES/ECB/PKCS5填充。 在 Java/Android 中,如果僅指定了AES [2] ,則提供程序決定使用哪種模式和填充,但通常它也是AES/ECB/PKCS5填充(如在我的機器上,Android 9,API 28)。 因此,算法的規范可能不是原因。 盡管如此,最好在 Java 代碼中使用完整規范AES/ECB/PKCS5Padding而不是AES

可能是在 Java 代碼中錯誤地使用了來自 Coldfusion 代碼的密鑰。 在 Coldfusion 中,密鑰通常使用generateSecretKey [3]生成,它返回 Base64 編碼的密鑰。 這意味着在 Android 代碼中,密鑰首先必須使用 Base64 解碼:

SecretKey secKey = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");

此外,如果密鑰是為 AES-128 生成的,則不會拋出異常,因為密鑰長 16 個字節,而 Base64 編碼僅為 24 個字節,這在當前的 Android 代碼中會生成相同長度的 AES 密鑰,因為

SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES"); 

因此,將使用 AES-192 而不是 AES-128,當然會產生不同的密文。

更新:正如評論中已經提到的,ECB 是一種不安全的操作模式,不應使用[4] 一個更安全的替代方案是 CBC [5] ,它在 Java/Android 和 Coldfusion [6]中都受支持。 更安全、更現代的是 GCM,這是一種經過身份驗證的加密算法,可以保證數據的真實性和機密性[7] ,如果支持,應該首選。 這里可以找到更多模式的描述[8]

加密需要比“AES”更多的細節,根據符號它必須是這樣的: AES/CBC/PKCS7Padding ,即它應該是:

Cipher.getInstance(transformation);

transformation應該由[Algorithm]/[Mode]/[Padding] ,可能值的范圍取決於底層密碼。 對於 Java,它是一種:

AES/CBC/NoPadding
AES/CBC/PKCS5Padding
AES/ECB/NoPadding
AES/ECB/PKCS5Padding
DES/CBC/NoPadding
etc...

如果在這種情況下不指定模式和填充,密碼將使用默認值。

我不知道 ColdFusion 端的默認值是什么,無論如何我建議在 ColdFusion 和 Android 端使用完整的規范,例如: AES/CBC/PKCS5Padding - 是一個很好的做法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM