C# 实现 JAVA AES加密解密[原创]
以下是网上普遍能收到的JAVA AES加密解密方法。
因为里面用到了KeyGenerator 和 SecureRandom,但是.NET 里面没有这2个类。无法使用安全随机数生成KEY。
我们在接收JAVA发送的AES加密字符串后,在.NET没有对应的KeyGenerator 和 SecureRandom去生成AES 的 KEY值,导致无法直接解密。
1 import java.security.SecureRandom; 2 import java.util.Base64; 3 4 import javax.crypto.Cipher; 5 import javax.crypto.KeyGenerator; 6 import javax.crypto.SecretKey; 7 import javax.crypto.spec.SecretKeySpec; 8 9 public class javaaes { 10 public static void main(String[] args) throws Exception{ 11 byte[] a = AesEncrypt("123456".getBytes(),"abcd1234"); 12 System.out.println(new String(Base64.getEncoder().encodeToString(a))); 13 } 14 //AES加密 15 public static byte[] AesEncrypt(byte[] byteContent, String password) throws Exception { 16 17 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 18 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 19 secureRandom.setSeed(password.getBytes()); 20 kgen.init(128, secureRandom); 21 22 SecretKey secretKey = kgen.generateKey(); 23 byte[] enCodeFormat = secretKey.getEncoded();//AES加密实际的Key值 24 //如果直接enCodeFormat=password.getBytes(),那.NET直接就可以解密 25 26 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); 27 28 Cipher cipher = Cipher.getInstance("AES"); 29 30 cipher.init(Cipher.ENCRYPT_MODE, key); 31 return cipher.doFinal(byteContent); 32 } 33 //AES解密 34 public static byte[] AesDecrypt(byte[] byteContent, String password) throws Exception { 35 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 36 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 37 secureRandom.setSeed(password.getBytes()); 38 kgen.init(128, secureRandom); 39 40 SecretKey secretKey = kgen.generateKey(); 41 byte[] enCodeFormat = secretKey.getEncoded(); 42 43 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); 44 Cipher cipher = Cipher.getInstance("AES"); 45 cipher.init(Cipher.DECRYPT_MODE, key); 46 return cipher.doFinal(byteContent); 47 } 48 49 }
第一种方法是,在JAVA中将AES的密钥直接生成出实际的key值,在.NET中用这个实际的key去解密。
1 public static void main(String[] args) throws Exception{ 2 String password = "1234567890";//AES的密钥 3 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 4 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 5 secureRandom.setSeed(password.getBytes()); 6 kgen.init(128, secureRandom); 7 8 SecretKey secretKey = kgen.generateKey(); 9 byte[] enCodeFormat = secretKey.getEncoded();//AES加密实际的Key值 10 System.out.println(new String(Base64.getEncoder().encodeToString(enCodeFormat))); 11 }
1 /// <summary> 2 /// AES解密 3 /// </summary> 4 /// <param name="data"></param> 5 /// <param name="key"></param> 6 /// <returns></returns> 7 public static string DeAES(byte[] content, string key) 8 { 9 using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider()) 10 { 11 aesProvider.Key = Convert.FromBase64String(key); 12 aesProvider.Mode = CipherMode.ECB; 13 aesProvider.Padding = PaddingMode.PKCS7; 14 using (ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor()) 15 { 16 byte[] inputBuffers = content; 17 byte[] results = cryptoTransform.TransformFinalBlock(inputBuffers, 0, inputBuffers.Length); 18 aesProvider.Clear(); 19 return Encoding.UTF8.GetString(results); 20 } 21 } 22 }
第二种方法是,下载IKVM ,解压缩后在VS的项目中引用bin目录下的IKVM.Runtime.dll、IKVM.OpenJDK.Core.dll、IKVM.OpenJDK.Security.dll
1 using java.security; 2 using javax.crypto; 3 using System.Security.Cryptography; 4 using System.Text; 5 using System; 6 7 public class Program 8 { 9 public static void Main() 10 { 11 byte[] a = Convert.FromBase64String("W0fSdgixanavXMiDdPXa/Q=="); 12 string result = DeAES(a, "abcd1234"); 13 Console.WriteLine(result); 14 Console.Read(); 15 } 16 /// <summary> 17 /// AES解密 18 /// </summary> 19 /// <param name="data"></param> 20 /// <param name="key"></param> 21 /// <returns></returns> 22 public static string DeAES(byte[] content, string key) 23 { 24 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 25 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 26 secureRandom.setSeed(Encoding.ASCII.GetBytes(key)); 27 kgen.init(128, secureRandom); 28 SecretKey secretKey = kgen.generateKey(); 29 byte[] enCodeFormat = secretKey.getEncoded(); 30 31 using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider()) 32 { 33 aesProvider.Key = enCodeFormat; 34 aesProvider.Mode = CipherMode.ECB; 35 aesProvider.Padding = PaddingMode.PKCS7; 36 using (ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor()) 37 { 38 byte[] inputBuffers = content; 39 byte[] results = cryptoTransform.TransformFinalBlock(inputBuffers, 0, inputBuffers.Length); 40 aesProvider.Clear(); 41 return Encoding.UTF8.GetString(results); 42 } 43 } 44 } 45 46 }