如何一步步實現JAVA與C# AES加密結果相同
阿新 • • 發佈:2018-12-09
實現JAVA與C# AES加密結果相同
最近公司開發一個電池溯源的介面,對方給的是一個java的demo,使用的是AES加密,但是我們的整合平臺是使用C#開發的,所有必須把java中的AES加密方法改成C#實現。對方給的demo如下
/**
* AES加密演算法
*
* @param content
* 加密內容
* @param password
* 密匙
* @return
*/
public static String encryptAES(String content, String password) {
try {
if (content == null || content.equalsIgnoreCase("")) {
return "";
}
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES" );
Cipher cipher = Cipher.getInstance("AES");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(1, key);
byte[] result = cipher.doFinal(byteContent);
String str = Base64.encode(result);
return str;
} catch (NoSuchAlgorithmException var13) {
var13.printStackTrace();
} catch (NoSuchPaddingException var14) {
var14.printStackTrace();
} catch (InvalidKeyException var15) {
var15.printStackTrace();
} catch (UnsupportedEncodingException var16) {
var16.printStackTrace();
} catch (IllegalBlockSizeException var17) {
var17.printStackTrace();
} catch (BadPaddingException var18) {
var18.printStackTrace();
}
return null;
}
改成c# 實現
//AES加密
public static string AesEncrypt(string str, string key)
{
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
RijndaelManaged rm = new RijndaelManaged
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
ICryptoTransform cTransform = rm.CreateEncryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
結果發現,JAVA和C#加密的結果不一樣,然後上網查資料,說是需要輸出SHA1後的真正金鑰,然後C#再利用這個祕密進行加密,,我把初始金鑰設定成123456,然後輸出C#真正的金鑰,程式碼如下:
try {
String password = "123456";//AES的金鑰
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();//AES加密實際的Key值
System.out.println(new String(java.util.Base64.getEncoder().encodeToString(enCodeFormat)));
}
catch (NoSuchAlgorithmException var13) {
var13.printStackTrace();
}
輸出後的金鑰放在C#裡面,加密的結果仍然不一樣。最後只能利用byte[]直接加密,
public static String encryptAES(String content, String password) {
try {
if (content == null || content.equalsIgnoreCase("")) {
return "";
}
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
//輸出byte
for(int i=0;i<enCodeFormat.length;i++)
{
int b=(int)enCodeFormat[i];
//java轉c#
b= b >= 0 ? (int)b : (int)(b + 256);
System.out.println(b);
}
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(1, key);
byte[] result = cipher.doFinal(byteContent);
String str = Base64.encode(result);
return str;
} catch (NoSuchAlgorithmException var13) {
var13.printStackTrace();
} catch (NoSuchPaddingException var14) {
var14.printStackTrace();
} catch (InvalidKeyException var15) {
var15.printStackTrace();
} catch (UnsupportedEncodingException var16) {
var16.printStackTrace();
} catch (IllegalBlockSizeException var17) {
var17.printStackTrace();
} catch (BadPaddingException var18) {
var18.printStackTrace();
}
return null;
}
byte輸出結果 107 180 131 126 183 67 41 16 94 228 86 141 218 125 198 126
c#利用byte進行加密
//AES加密
public static string AesEncrypt(string str, string key)
{
byte[] b = new byte[] { 107, 180, 131, 126, 183, 67, 41, 16, 94, 228, 86, 141, 218, 125, 198, 126 };
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
RijndaelManaged rm = new RijndaelManaged
{
Key = b,//Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
ICryptoTransform cTransform = rm.CreateEncryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
此時,兩邊的加密結果終於一致了。