简体   繁体   English

AES 256 Java和.Net兼容的加密和解密?

[英]AES 256 java and .Net compatible encryption and decryption?

I want to do the AES 256 encryption/decryption using Java and .Net. 我想使用Java和.Net进行AES 256加密/解密。 Which Means i should be able to encrypt with Java and decrypt with .Net and Vice vesra. 这意味着我应该能够使用Java进行加密,并能够使用.Net和Vice vesra进行解密。 Following is the Java AES 256 encryption. 以下是Java AES 256加密。

byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
System.out.println(Cipher.getMaxAllowedKeyLength("AES"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
return new String(Base64.encodeBase64(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));

1) The Java-decryption part is given by 1)Java解密部分由

byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
return new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt.getBytes("UTF-8"))));

where strToDecrypt are the Base64 encoded encrypted data (given by the return value of the encryption part) and which deviates from the encryption part only in the last two lines. 其中strToDecrypt是Base64编码的加密数据(由加密部分的返回值提供),仅在最后两行与加密部分有所不同。

Note: In practice, the IV should be randomly generated (eg Generating random IV for AES in Java ). 注意:实际上,应该随机生成IV (例如,在Java中为AES生成随机IV )。 But I assume that's clear and the 0-sequence is just for testing purposes. 但是我认为这很清楚,0序列仅用于测试目的。

2) Concerning the key derivation PBKDF2WithHmacSHA256 the C#-solution depends on your .NET-framework version. 2)关于密钥派生PBKDF2WithHmacSHA256 ,C#解决方案取决于您的.NET-framework版本。 For V4.7.2 and above the key can be derived with: 对于V4.7.2及更高版本,可以使用以下方法派生密钥:

// .NET Framework 4.7.2 +
byte[] secretKey = null;
using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(KEY, Encoding.UTF8.GetBytes(SALT), 65536, HashAlgorithmName.SHA256))   
{
    secretKey = rfc2898.GetBytes(32);                                                                                                                                                                                
}

Note: Previous implementations (prior to v4.7.2) of Rfc2898DeriveBytes use SHA1 (hard coded) instead of SHA256 and thus, there's no ctor expecting 4 parameters. 注:先前的实现(之前V4.7.2)的Rfc2898DeriveBytes使用SHA1 (硬编码)代替SHA256 ,因此,也没有构造函数期望4个参数。 Moreover, the Rfc2898DeriveBytes -class requires a salt-length of at least 8 bytes, otherwise a System.ArgumentException: Salt is not at least eight bytes is thrown. 此外, Rfc2898DeriveBytes类需要的盐长度至少为8个字节,否则,将抛出System.ArgumentException: Salt is not at least eight bytes

An alternative is: 一种替代方法是:

// .NET Framework 4.5 + 
byte[] secretKey = null;
KeyDerivationPrf keyDerivationPrf = KeyDerivationPrf.HMACSHA256;
secretKey = KeyDerivation.Pbkdf2(KEY, Encoding.UTF8.GetBytes(SALT), keyDerivationPrf, 65536, 32);

The latter works for V4.6.1 and above, but you need the Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivation -class which you can find eg at https://www.nuget.org/packages/Microsoft.AspNetCore.Cryptography.KeyDerivation/ . 后者适用于V4.6.1及更高版本,但您需要Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivation -class,您可以在https://www.nuget.org/packages/Microsoft.AspNetCore.Cryptography.KeyDerivation中找到该类。 / For the installation you can use eg the Package Manager Console (Tools - NuGet Package Manager - Package Manager Console). 对于安装,您可以使用例如程序包管理器控制台(工具-NuGet程序包管理器-程序包管理器控制台)。 Just enter the corresponding command as described in the link. 只需按链接中所述输入相应的命令。 Maybe you get an IDE-error CS0012 . 也许您会收到IDE错误CS0012 In this case you have to add <Reference Include="netstandard" /> to the reference-section of your csproj -file (see also https://github.com/dotnet/standard/issues/542 ). 在这种情况下,您必须将<Reference Include="netstandard" />csproj -file的参考部分(另请参见https://github.com/dotnet/standard/issues/542 )。 The KeyDerivationPrf -class doesn't restrict the salt-length. KeyDerivationPrf -class不限制盐长度。

There are also other possibilities (like Bouncy Castle) which I didn't try, but maybe they are better alternatives for you. 还有其他我没有尝试过的可能性(例如Bouncy Castle),但也许它们是您的更好选择。 This topic is also discussed at Rfc2898 / PBKDF2 with SHA256 as digest in c# . Rfc2898 / PBKDF2上也以SHA256作为c#中的摘要讨论了该主题。

3) An example for the C#-encryption-method is: 3)C#加密方法的一个示例是:

public string Encrypt(string plainText)
{
    // PBKDF2WithHmacSHA256 Key derivation
    // ...

    using (RijndaelManaged cipher = new RijndaelManaged())
    {
        cipher.Key = secretKey;
        cipher.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        cipher.Mode = CipherMode.CBC;
        cipher.Padding = PaddingMode.PKCS7;

        byte[] encryptedData;
        using (ICryptoTransform encryptor = cipher.CreateEncryptor())
        {
            using (System.IO.MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }
                    encryptedData = memoryStream.ToArray();
                }
            }
        }

        return Convert.ToBase64String(encryptedData);
    }
}

where plainText is a string containing your plain text (corresponding to strToEncrypt ). 其中plainText是包含纯文本的字符串(对应于strToEncrypt )。 The encrypted data become base64 encoded and are returned as string (analogous to your Java-method). 加密的数据将进行base64编码,并以字符串形式返回(类似于Java方法)。

Test case: 测试用例:

String KEY = "The Password";
String SALT = "The Salt";
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

gives

Plain text:       This is a plain text that needs to be encrypted
Key (hex):        2D7664713D701C58FC506F93CEA3194671AD3B5C034255A4AC04AF46EADC89BC
Base64 encoded
encrypted data:   ksUYjmbP9ga39LXr3wXQ34Bp32UlloYPxg3WWuW0iovWbg/GxHJrIuF3jrDvjr/Q

4) An example for the C#-decryption-method is: 4)C#解密方法的一个示例是:

public string Decrypt(string encryptedText)
{
    // PBKDF2WithHmacSHA256 Key derivation
    // ...

    using (RijndaelManaged cipher = new RijndaelManaged())
    {
        cipher.Key = secretKey;
        cipher.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        cipher.Mode = CipherMode.CBC;
        cipher.Padding = PaddingMode.PKCS7;

        string decryptedText;
        using (ICryptoTransform decryptor = cipher.CreateDecryptor())
        {
            using (System.IO.MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(encryptedText)))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader streamReader = new StreamReader(cryptoStream))
                    {
                        decryptedText = streamReader.ReadToEnd();
                    }
                }
            }
        }

        return decryptedText;
    }
}

where encryptedText is the return value of the encryption-part (encrypted data which are base64 encoded, corresponding to strToDecrypt ). 其中encryptedText是加密部分的返回值(加密其是base64编码数据,对应于strToDecrypt )。 The method returns the decrypted text (analogous to the Java-method). 该方法返回解密的文本(类似于Java方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM