最近公司开发一个电池溯源的接口,对方给的是一个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;iint 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);
}
此时,两边的加密结果终于一致了。