.NET AES 加密和 Android 解密

.NET AES Encryption and Android Decryption

我正在使用以下代码在 .NET 中使用 AES 加密 GUID 字符串。

        // Decode the challenge bytes from base 64
        byte[] challengeBytes = Base64.decode(challenge, Base64.NO_WRAP);

        ICryptoTransform encryptor = aes.CreateEncryptor(key, initializationVector);

        MemoryStream memoryStream = new MemoryStream();

        // Create a stream to encrypt our data
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(challenge, 0, challenge.Length);
        cryptoStream.FlushFinalBlock();

        byte[] encryptedChallengeBytes = memoryStream.ToArray();

        // Clean up
        memoryStream.Close();
        cryptoStream.Close();

        // Convert to a base 64 string
        return Convert.ToBase64String(encryptedChallengeBytes, Base64FormattingOptions.None);

然后在Android我用下面的代码解密

    Cipher aes = Cipher.getInstance("AES/CBC/PKCS7Padding");

    SecretKey key = new SecretKeySpec(keyBytes, "AES");

    // Initialize the cipher
    aes.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(initializationVector));

    guid = new String(aes.doFinal(challengeBytes));

    return guid;

我已经完成了各种调试和 IVKeyChallenge Bytes 在两个平台上完全相同。我逐字节查看它们,它们很好。它们唯一的区别是,在 .NET 上,它们的范围是 0-255,而在 Android 上,它们的范围是 -128 到 127。现在我不确定这是否是问题所在,但我只是假设 2 的补码应该' 影响算法的 Java 实现,因为在我看来那是愚蠢的。

我在尝试解密时遇到此异常

03-01 20:31:48.313  12886-12982/com.danielwardin.social I/SOCIAL﹕ eneter.messaging.messagingsystems.simplemessagingsystembase.internal.DefaultDuplexOutputChannel@2474079b
03-01 20:32:50.157  12886-12988/com.danielwardin.social W/System.err﹕ javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
03-01 20:32:50.158  12886-12988/com.danielwardin.social W/System.err﹕ at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
03-01 20:32:50.187  12886-12988/com.danielwardin.social W/System.err﹕ at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)
03-01 20:32:50.188  12886-12988/com.danielwardin.social W/System.err﹕ at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466)
03-01 20:32:50.188  12886-12988/com.danielwardin.social W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1340)

这是导致问题的线路

    guid = new String(aes.doFinal(challengeBytes));

challengebytes 数组总是 48 字节,也是 16 的倍数所以我不知道为什么我得到 BadPaddingException.

我查看了所有 Google 并调整了大约 4 个小时,我的大脑现在已经死了。

有什么想法吗?

PKCS7Padding 是一种始终填充的填充方案。当明文是块长度的倍数时,则添加一个附加块,每个字节设置为块长度的值(模 256)。这消除了歧义:如果纯文本的最后一个字节是 01 怎么办?它看起来像 1 个字节的填充并被剥离。

因此,只需从 Java 中构造密码的位置删除它,因为您实际上并未使用填充方案:

Cipher aes = Cipher.getInstance("AES/CBC/NoPadding");

--编辑: 抱歉,我混淆了语义。查看更多信息 here