将CryptoJS哈希生成代码转为C#结果不符,求问题排查
CryptoJS哈希转C#代码结果不一致的问题排查与修复
你需要将一段CryptoJS生成哈希的JavaScript代码转换为C#代码,但两者结果不一致。
原JavaScript代码
var to_md5 = "Some Text Here" var hash = CryptoJS.SHA1(CryptoJS.MD5(to_md5.toUpperCase()).toString()); var result = CryptoJS.enc.Hex.stringify(hash); console.log(result);
你编写的C#代码
var to_md5 = "Some Text Here".ToUpper(); var hashString = gSHA1(gMD5(to_md5)); private string gMD5(string input) { MD5 md5 = MD5.Create(); Byte[] inputBytes = Encoding.ASCII.GetBytes(input); Byte[] hash = md5.ComputeHash(inputBytes); StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("X2")); } return sb.ToString(); } private string gSHA1(string s) { Byte[] bytes = Encoding.UTF8.GetBytes(s); var sha1 = SHA1.Create(); Byte[] hashBytes = sha1.ComputeHash(bytes); return HexStringFromBytes(hashBytes); } private string HexStringFromBytes(Byte[] bytes) { var sb = new StringBuilder(); foreach (byte b in bytes) { var hex = b.ToString("x2"); sb.Append(hex); } return sb.ToString(); }
问题根源
你的C#代码存在两处关键差异,导致结果不匹配:
- 编码不一致:CryptoJS处理字符串时默认使用UTF-8编码,而你的
gMD5方法用了Encoding.ASCII,虽当前测试文本是纯英文,但编码差异会在有非ASCII字符时放大问题,且不符合CryptoJS的默认行为。 - MD5哈希字符串大小写不匹配:CryptoJS的
MD5(...).toString()返回的是小写十六进制字符串,而你的gMD5方法用ToString("X2")生成了大写字符串。SHA1是对这个字符串的字节进行哈希,大小写不同会导致字节数组完全不同,最终SHA1结果自然不一致。
修正后的C#代码
var to_md5 = "Some Text Here".ToUpper(); var hashString = gSHA1(gMD5(to_md5)); private string gMD5(string input) { MD5 md5 = MD5.Create(); // 改用UTF-8编码,匹配CryptoJS默认行为 Byte[] inputBytes = Encoding.UTF8.GetBytes(input); Byte[] hash = md5.ComputeHash(inputBytes); StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { // 生成小写十六进制字符串,匹配CryptoJS的输出 sb.Append(hash[i].ToString("x2")); } return sb.ToString(); } private string gSHA1(string s) { Byte[] bytes = Encoding.UTF8.GetBytes(s); var sha1 = SHA1.Create(); Byte[] hashBytes = sha1.ComputeHash(bytes); return HexStringFromBytes(hashBytes); } private string HexStringFromBytes(Byte[] bytes) { var sb = new StringBuilder(); foreach (byte b in bytes) { var hex = b.ToString("x2"); sb.Append(hex); } return sb.ToString(); }
验证说明
修正后,C#代码的流程和CryptoJS完全对齐:
- 将输入文本转为大写
- 用UTF-8编码生成MD5哈希,输出小写十六进制字符串
- 对该小写字符串用UTF-8编码生成SHA1哈希,最终输出小写十六进制结果
此时两者生成的哈希值会完全一致。
内容的提问来源于stack exchange,提问作者Firas Shrourou
相关产品推荐
相关产品推荐

