HMAC-C#和JavaScript给出了不同的结果
我的问题类似于,但因为问题缺少一些细节,答案也不是很有用,所以我再次提问,但有更多细节 我已经实现了基于HMAC的安全性,它基于 我有一个可以正常工作的C#应用程序,可以创建正确的头文件(我特意设置了静态时间戳和nonce,只是为了测试): 这将计算此标头:HMAC-C#和JavaScript给出了不同的结果,javascript,c#,security,hmac,Javascript,C#,Security,Hmac,我的问题类似于,但因为问题缺少一些细节,答案也不是很有用,所以我再次提问,但有更多细节 我已经实现了基于HMAC的安全性,它基于 我有一个可以正常工作的C#应用程序,可以创建正确的头文件(我特意设置了静态时间戳和nonce,只是为了测试): 这将计算此标头:test:fhqxcZll+3ZRQi3vRexbNyoT00Yqdoyq3CrAdGQ+4kE=:715de35a4bfd4912baa16daef21992d:1521622403 不是,我正在尝试创建Postman预请求脚本,该脚本将生
test:fhqxcZll+3ZRQi3vRexbNyoT00Yqdoyq3CrAdGQ+4kE=:715de35a4bfd4912baa16daef21992d:1521622403
不是,我正在尝试创建Postman预请求脚本,该脚本将生成相同的头。这是我的剧本:
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var CLIENT_KEY = 'test';
var SECRET_KEY = 'A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc=';
var requestTimeStamp = "1521622403";
var nonce = "715de35a4bfd4912baaa16daef21992d"
requestUrl = requestUrl.toLowerCase();
var signatureRawData = CLIENT_KEY+requestUrl+requestTimeStamp+nonce;
console.log("signatureRawData: "+signatureRawData);
var x = CryptoJS.enc.Utf8.parse(SECRET_KEY);
var hash = CryptoJS.HmacSHA256(signatureRawData, x);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var header = [CLIENT_KEY, hashInBase64, nonce, requestTimeStamp].join(":");
console.log("header: "+ header);
return header;
}
postman.setEnvironmentVariable('hmacAuthHeader', getAuthHeader(request['method'], request['url'], request['data']));
但我得到的标题值不同:
test:2ITrhVxr1/4boxnvncecnash0c36limzwvq0davency=:715de35a4bfd4912baa16daef21992d:1521622403
在C#中,我正在将密钥和数据转换为散列到字节[]
,这可能就是问题所在。如何在JavaScript中执行相同的操作?C#需要
byte[]
作为HMACSHA256
和ComputeHash
中的参数
我正在寻找一种从C#和JavaScript(Postman预请求脚本)生成相同的HMACSHA256的方法。在JS中纠正哈希的解决方案是关键。在C#我打电话:
byte[]secretKeyByteArray = Convert.FromBase64String(apiKey);
在使用该键之前,我在JS中传递原始的base64编码值
以下是更正的请求前脚本:
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function GetNonce() {
return (S4() + S4() + S4()+ S4() + S4() + S4() + S4()+ S4()).toLowerCase();
}
function GetTimeStamp() {
var d = new Date();
return Math.round(d.getTime() / 1000);
}
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var CLIENT_KEY = postman.getEnvironmentVariable('api_user');
var SECRET_KEY = postman.getEnvironmentVariable('api_key');
var AUTH_TYPE = 'HMAC';
var requestTimeStamp = GetTimeStamp();
var nonce = GetNonce();
requestUrl = requestUrl.toLowerCase();
var signatureRawData = [CLIENT_KEY,requestUrl,requestTimeStamp,nonce].join("");
var key = CryptoJS.enc.Base64.parse(SECRET_KEY);
var hash = CryptoJS.HmacSHA256(signatureRawData, key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var header = [CLIENT_KEY, hashInBase64, nonce, requestTimeStamp].join(":");
console.log("header: "+ header);
return AUTH_TYPE+" "+header;
}
postman.setEnvironmentVariable('hmacAuthHeader', getAuthHeader(request['method'], request['url'], request['data']));
当我搜索解决方案时,我发现了很多语言的hmac sha256实现列表:以及获得给定输出的目标
url
是什么?在javascript中,您也可以执行CryptoJS.enc.Utf8.parse(SECRET\u KEY)
,它假定密钥是UTF-8字符串(实际上不是),而在C中,您可以正确地转换.FromBase64String(apiKey)。在C#中,出于某种原因,您也会执行Uri.EscapeUriString
,但在javascript中,您不会这样做(通过encodeURI
或类似方式)。@Evk很抱歉没有指定该参数-http://localhost:63564/test/secure
@Evk我想我有办法了。在C#中,我在键上使用FromBase64String
,但在JavaScript中没有这样做。添加CryptoJS.enc.Base64.parse(秘钥)似乎解决了这个问题。我会检查tjat并发布答案,如果它有效的话。这不是我在上面的评论中说的吗?:)
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function GetNonce() {
return (S4() + S4() + S4()+ S4() + S4() + S4() + S4()+ S4()).toLowerCase();
}
function GetTimeStamp() {
var d = new Date();
return Math.round(d.getTime() / 1000);
}
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var CLIENT_KEY = postman.getEnvironmentVariable('api_user');
var SECRET_KEY = postman.getEnvironmentVariable('api_key');
var AUTH_TYPE = 'HMAC';
var requestTimeStamp = GetTimeStamp();
var nonce = GetNonce();
requestUrl = requestUrl.toLowerCase();
var signatureRawData = [CLIENT_KEY,requestUrl,requestTimeStamp,nonce].join("");
var key = CryptoJS.enc.Base64.parse(SECRET_KEY);
var hash = CryptoJS.HmacSHA256(signatureRawData, key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var header = [CLIENT_KEY, hashInBase64, nonce, requestTimeStamp].join(":");
console.log("header: "+ header);
return AUTH_TYPE+" "+header;
}
postman.setEnvironmentVariable('hmacAuthHeader', getAuthHeader(request['method'], request['url'], request['data']));