最近需要在nodejs上加密jwt,C#端解密jwt得到用戶信息
class JwtService extends Service {
encrypt(content) {
const secretkey = this.app.config.jwt.key // 唯一(公共)祕鑰
const cipher = crypto.createCipher('aes-128-ecb', secretkey) // 使用aes128加密
let enc = cipher.update(content, 'utf8', 'hex') // 編碼方式從utf-8轉爲hex;
enc += cipher.final('hex')// 編碼方式轉爲hex;
return enc
}
}
卻發現C#端怎麼也解密不了,一直報錯,改了一整天,後來終於發現,nodejs端加密用的key其實在使用之前已經使用md5加密了一次,服務端如果需要使用這個key解密,則需要也同樣使用MD5加密
public static string AesDecrypt(string content, string key)
{
// nodejs aes加密默認的key使用了md5加密,所以C#解密的key也要默認使用md5
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = Encoding.UTF8.GetBytes(key);
byte[] keyArray = md5.ComputeHash(output);
byte[] toEncryptArray = HexStringToBinary(content);
RijndaelManaged des = new RijndaelManaged();
des.Key = keyArray;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = des.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
代碼使用了一個函數把16進制轉成字節數組
public static byte[] HexStringToBinary(string hexstring)
{
var inputByteArray = new byte[hexstring.Length / 2];
for (var x = 0; x < inputByteArray.Length; x++)
{
var i = Convert.ToInt32(hexstring.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
return inputByteArray;
}
解決問題,卻花費一天時間