关于Java-AES-SHA1PRNG转C#AES加密相关问题,今天我们一起学习探讨一下。
java 源码
public static String AesEncrypt(String data,String key) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes());
kgen.init(128, secureRandom);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encryptedData = cipher.doFinal(data.getBytes("UTF-8"));
return byteArr2HexStr(encryptedData);
}catch (Exception e){
throw new RuntimeException(e);
}
}
private static String byteArr2HexStr(byte[] b) {
int length = b.length;
StringBuffer sb = new StringBuffer(length * 2);
for (int i = 0; i < length; i++) {
int temp = b[i];
while (temp < 0) {
temp = temp + 256;
}
if (temp < 16) {
sb.append("0");
}
sb.append(Integer.toString(temp, 16));
}
return sb.toString();
}
分析:采用AES加密,秘钥进行了二次生成,采用的是SHA1PRNG,加密结果为Hex的字符串。
string content = “idkjdalkkmkdmadasfdasfdas”;
string encryptKey = “4545124124lokqjdmsa”;
C#源码
从java代码中发现,秘钥是经过sha1重新生成的,所以先写一个秘钥转化的方法
/// <summary>
/// 获取Aes重新生成的key(sha1法)
/// </summary>
/// <returns></returns>
private static byte[] GetAesKey(string key)
{
byte[] keyByte = Encoding.UTF8.GetBytes(key);
using (var st = new SHA1CryptoServiceProvider())
{
using (var sha1 = new SHA1CryptoServiceProvider())
{
var endByte = sha1.ComputeHash(st.ComputeHash(keyByte));
byte[] keyArray = endByte.Take(16).ToArray();
return keyArray;
}
}
}
加密结果为Hex的字符串,所以需要写一个转为Hex的方法
/// <summary>
/// byte数组Hex编码
/// </summary>
/// <param name="bytes">需要进行编码的byte[]</param>
/// <returns></returns>
private static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
{
string hexString = string.Empty;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString("x2"));
}
hexString = strB.ToString();
}
return hexString;
}
接下来就是AES加密
/// <summary>
/// Aes加密,key被sha1重新生成
/// </summary>
/// <param name="str"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string AesEncrypt_sha1key(string str, string key)
{
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
RijndaelManaged rm = new RijndaelManaged
{
Key = GetAesKey(key),
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
ICryptoTransform cTransform = rm.CreateEncryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return ToHexString(resultArray);
}
结果展示
从两个结果图我们可以看到
明文:idkjdalkkmkdmadasfdasfdas
秘钥:4545124124lokqjdmsa
java的加密结果:23deb5e8c6b852bb642014c6da52180a5e3e36e9a9b162ac21ca4848c56cf970
C#的加密结果:
23deb5e8c6b852bb642014c6da52180a5e3e36e9a9b162ac21ca4848c56cf970
结果一致
希望对大家有帮助。