我试图使用Crypto.js库在javascript中模拟以下.NET代码。
var hashInput = "public=ID1000000001::routetype=POST::route=personsearch::key1=ID1000000001::key2=1043"
byte[] inputBytes = new byte[hashInput.Length * sizeof(char)];
System.Buffer.BlockCopy(hashInput.ToCharArray(), 0, inputBytes,0,inputBytes.Length);
byte[] keyBytes = HexadecimalStringToByteArray("A_HEX_STRING_GOES_HERE");
var hmac = HMACSHA256.Create();
hmac.Key = keyBytes;
var clientHash = hmac.ComputeHash(inputBytes);
这给了我一个ByteArray,它以一种形式用作POST的一部分到WebAPI [41,197,254,91,244,87 .....]等。
我想在javascript客户端中创建相同的字节数组,但我很难得到这个。我尝试过以下方法:
var stringToHash = 'public=ID1000000001::routetype=POST::route=personsearch::key1=ID1000000001::key2=1043';
var privateKey = 'A_HEX_STRING_GOES_HERE';
var hash = CryptoJS.HmacSHA256(stringToHash, privateKey);
//this results in a WordArray, which can be converted to many types
//however i cannot get the byte array as in the .net example
//i.e. i just want to get [41,197,254,91,244,87....] etc.
我可以在Crypto.js的文档中看到如何转换为base64和其他格式,但不能转换为我需要的ByteArray。
有什么想法吗?
- UPDATE 感谢不使用BlockCopy的建议,也指出了我完全忽略的编码问题的方向。
这是问题的一部分。另一部分是我设法滥用HMACSHA256类。我发现(经过几个小时,几个小时后).NET代码没有产生正确的哈希值。
事实证明这个代码DID产生了正确的哈希:
var hashInput = "a::string::to::hash";
var privateKey = "C0B615950F9D577A4EAF64C9B4F2E50F3DA2C6BB6F790FA346E9732788B29A08AC5444F1B82984DB190A75D3861CC4802D598EBF0025FD1C327928F43EB1C80E";
byte[] inputBytes = Encoding.UTF8.GetBytes(hashInput);
byte[] keyBytes = Encoding.UTF8.GetBytes(privateKey);
HMACSHA256 hmac = new HMACSHA256(keyBytes);
hmac.Initialize();
var clientHash = hmac.ComputeHash(inputBytes);
var base64 = Convert.ToBase64String(clientHash);
幸运的是我的WebAPI尚未上线!
答案 0 :(得分:0)
问题可能是字符编码。您应该使用JavaScript中的方法encode_utf8(stringValue)
和.NET中的new UTF8Encoding.getBytes(String value)
来确保字符编码匹配。请注意,现代加密基于字节,而不是字符串或字符。使用System.Buffer.BlockCopy()
对字符进行编码实际上是不好的做法。