Java .NET AES加密和Android解密

Java .NET AES加密和Android解密,java,c#,android,encryption,cryptography,Java,C#,Android,Encryption,Cryptography,我正在使用以下代码在.NET中使用AES加密GUID字符串 // Decode the challenge bytes from base 64 byte[] challengeBytes = Base64.decode(challenge, Base64.NO_WRAP); ICryptoTransform encryptor = aes.CreateEncryptor(key, initializationVector);

我正在使用以下代码在.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);
    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;
然后在Android中,我用下面的代码解密

        // 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);
    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;
我已经做了各种调试,IV挑战字节在两个平台上完全相同。我已经一个字节一个字节地看了,它们很好。它们唯一的区别是,在.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

我已经在谷歌搜索了4个小时,调整了一下,现在我的大脑已经死了


有什么想法吗?

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

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

Cipher aes = Cipher.getInstance("AES/CBC/NoPadding");
--编辑:
对不起,我把语义弄错了。请参阅更多信息。

问题在于您遇到了它无法识别的问题java.security.nosuchagorithmexception:无效转换:AES/CBC它接受AES或AES/CBC/PKCS7Padding格式。如果指定.NET中的modeYes默认值为PKCS7和CBC,则填充是必需的。我在MSDN上查过了。我现在已经设法解决了。在你让我意识到填充是不必要的之后,我做了一些研究,构造器接受了
AES/CBC/NoPadding
,就像你现在的编辑:)是的,我同时意识到了这一点,并删除了我前面的评论。我将尝试记住.NET上的默认设置。