Java / Net与AES之间的Interopencryption/解密以及指定IV和密钥

我正在尝试使用AES来实现对称encryption,其中指定了密钥和IV。 在每个生态系统(Java-> Java / .NET-> .NET)中,encryption和解密都是按照devise的方式工作的,但是如果我试图在两者之间进行操作,我会遇到大量有关填充等的错误。

我已经阅读了几个post,包括http://blogs.msdn.com/b/dotnetinterop/archive/2005/01/24/java-and-net-aes-crypto-interop.aspx,但似乎没有相同的用例。 这是我的代码:

JAVA

public class Main { public static void main(String[] args) throws Exception { String data = "Something to decrypt"; String encrypt = Encrypt(data); System.out.println(encrypt); String decrypt = Decrypt(encrypt); System.out.println(decrypt); } private static String Encrypt(String raw) throws Exception { Cipher c = getCipher(Cipher.ENCRYPT_MODE); byte[] encryptedVal = c.doFinal(raw.getBytes("UTF-8")); return new BASE64Encoder().encode(encryptedVal); } private static Cipher getCipher(int mode) throws Exception { Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding", new SunJCE()); //a random Init. Vector. just for testing byte[] iv = "e675f725e675f725".getBytes("UTF-8"); c.init(mode, generateKey(), new IvParameterSpec(iv)); return c; } private static String Decrypt(String encrypted) throws Exception { byte[] decodedValue = new BASE64Decoder().decodeBuffer(encrypted); Cipher c = getCipher(Cipher.DECRYPT_MODE); byte[] decValue = c.doFinal(decodedValue); return new String(decValue); } private static Key generateKey() throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); char[] password = "Pass@word1".toCharArray(); byte[] salt = "S@1tS@1t".getBytes("UTF-8"); KeySpec spec = new PBEKeySpec(password, salt, 65536, 128); SecretKey tmp = factory.generateSecret(spec); byte[] encoded = tmp.getEncoded(); return new SecretKeySpec(encoded, "AES"); } } 

。净

 internal class Program { private static void Main(string[] args) { string encrypted = Encrypt("Something to decrypt"); Console.Out.WriteLine(encrypted); string decrypted = Decrypt(encrypted); Console.Out.WriteLine(decrypted); Console.Out.WriteLine("Press any key to continue"); Console.ReadKey(); } private static string Encrypt(string raw) { using (var csp = new AesCryptoServiceProvider()) { ICryptoTransform e = GetCryptoTransform(csp, true); byte[] inputBuffer = Encoding.UTF8.GetBytes(raw); byte[] output = e.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length); string encrypted = Convert.ToBase64String(output); return encrypted; } } public static string Decrypt(string encrypted) { using (var csp = new AesCryptoServiceProvider()) { var d = GetCryptoTransform(csp, false); byte[] output = Convert.FromBase64String(encrypted); byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length); string decypted = Encoding.UTF8.GetString(decryptedOutput); return decypted; } } private static ICryptoTransform GetCryptoTransform(AesCryptoServiceProvider csp, bool encrypting) { csp.Mode = CipherMode.CBC; csp.Padding = PaddingMode.PKCS7; var passWord = "Pass@word1"; var salt = "S@1tS@lt"; //a random Init. Vector. just for testing String iv = "e675f725e675f725"; var spec = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(passWord), Encoding.UTF8.GetBytes(salt), 65536); byte[] key = spec.GetBytes(16); csp.IV = Encoding.UTF8.GetBytes(iv); csp.Key = key; if (encrypting) { return csp.CreateEncryptor(); } return csp.CreateDecryptor(); } } 

应用程序的输出是:

JAVA

 EO88Y8EjPAbaiZGoQM47z5i3vvy8jgVoehCPJDQES/4= Something to decrypt 

。净

 T/m/GatOCvFEJ4frVIoY8CbuQ1av97HoKdhUhAZcXp0= Something to decrypt 

当我尝试在Java中解密.NETstring时,我得到:线程“main”中的exceptionjavax.crypto.BadPaddingException:给定的最终块未正确填充。

在.NET中,我得到类似的:System.Security.Cryptography.CryptographicException未处理HResult = -2146233296消息=填充无效,无法删除。

在.NET中,我使用Rfc2898DeriveBytes来生成基于密码,盐和迭代次数的密钥。 我猜测这是根本原因,因为在Java中我使用SecretKeyFactory希望达到相同的结果。 但是,如果这是原因,我不知道如何调和两个…?

谢谢你的帮助。

**更新 – 解决**

男孩,我感觉比平常笨重。 问题是我的代码中有一个错字。 .NET盐值具有“1”和“L”,其中Java盐值具有“1”和“1”。 纠正这个错误解决了这个问题。 对不起,浪费任何人的时间。

。净

 var salt = "S@1tS@lt"; 

Java的

 byte[] salt = "S@1tS@1t"