AES加密Java和解密在C# [英] AES Encryption in Java and Decryption in C#

查看:115
本文介绍了AES加密Java和解密在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我加密的十六进制字符串,并已使用标准的AES算法加密的密钥。
code:

Hello I've Encrypted Hex string and Key that has been encrypted using standard AES Algorithm. Code:

        final String key = "=abcd!#Axd*G!pxP";
        final javax.crypto.spec.SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
        final javax.crypto.Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        byte [] encryptedValue = cipher.doFinal(input.getBytes());
        return new String(org.apache.commons.codec.binary.Hex.encodeHex(encryptedValue));

现在我尝试解密使用C#它
code:

Now I try to decrypt it using C# Code:

            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            // Assumed Mode and padding values.
            rijndaelCipher.Mode = CipherMode.ECB;
            rijndaelCipher.Padding = PaddingMode.None;

            // AssumedKeySize and BlockSize values.
            rijndaelCipher.KeySize = 0x80;
            rijndaelCipher.BlockSize = 0x80;
            // Convert Hex keys to byte Array.
            byte[] encryptedData = hexStringToByteArray(textToDecrypt);

            byte[] pwdBytes = Encoding.Unicode.GetBytes(key);
            byte[] keyBytes = new byte[0x10];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length)
            {
                len = keyBytes.Length;
            }
            Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            rijndaelCipher.IV = keyBytes;
            // Decrypt data
            byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            str = Encoding.UTF8.GetString(plainText);

    static private byte[] HexToBytes(string str)
    {
        if (str.Length == 0 || str.Length % 2 != 0)
            return new byte[0];
        byte[] buffer = new byte[str.Length / 2];
        char c;
        for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
        {
            // Convert first half of byte   
            c = str[sx];
            buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);
            // Convert second half of byte    
            c = str[++sx];
            buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
        }
        return buffer;
    } 

但并不如预期的输出。
请指出我要去哪里错了?

but the output is not as expected. Please point out where I'm going wrong?

推荐答案

您code有一个很大的问题:它是混合字符编码

Your code has one big problem: It is mixing the character encodings!

在Java中,你正在调用 key.getBytes(),不带参数。该方法根据您的操作系统和Java中的默认字符集上返回UTF-8或CP1252 / ISO 8859-1 EN codeD数据。

In Java you are calling key.getBytes(), without arguments. This method returns the UTF-8 or CP1252/ISO 8859-1 encoded data depending on your operating system and the default charset in Java.

在C#侧您使用 Encoding.Uni code.GetBytes(键) - 统一code使用.NET是双字节字符别名的代名词UTF-16(Little-端)。因此,你正在使用C#不同的密钥。

On C# side you are using Encoding.Unicode.GetBytes(key) - "Unicode" in .Net is a synonym for double byte characters alias UTF-16 (Little-Endian). Therefore you are using a different key in C#.

您应该能够通过比较Java和C#的字节数,看的区别:

You should be able to see the difference by comparing the number of bytes in Java and C#:

Java的:!= ABCD#AXD * G PXP.getBytes()长度= 16

C#: Encoding.Uni code.GetBytes(!= ABCD#AXD * G PXP)长度= 32

我强烈建议你使用的字节数组,而不是字符串定义加密密钥。

I strongly recommend you to use byte arrays instead of Strings for defining a cryptographic key.

更新:另一个区别是,你要设置在C#中的初始化向量(IV),你不要在Java中做的。当您使用的是欧洲央行IV不应使用,但如果你改变CBC例如这使得一个很大的区别。

Update: Another difference is that you are setting an initialization vector (IV) in C# which you don't do in Java. As you are using ECB the IV should not be used but if you change to CBC for example this makes a big difference.

这篇关于AES加密Java和解密在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆