我的问题类似于HMAC C# and JavaScript,但由于问题缺乏一些细节,答案不是很有帮助,我会再次提出问题,但有更多细节。
我已经实施了基于this tutorial的基于HMAC的安全性。
我有一个可以创建正确标头的C#应用程序(我故意设置静态时间戳和nonce - 仅用于测试):
private string CreateHeader(string url)
{
string appId = "test";
string apiKey = "A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc=";
string requestTimeStamp = "1521622403";
string nonce = "715de35a4bfd4912baaa16daef21992d";
url = Uri.EscapeUriString(url.ToLower());
string signatureRawData = String.Format("{0}{1}{2}{3}", appId, url, requestTimeStamp, nonce);
byte[]secretKeyByteArray = Convert.FromBase64String(apiKey);
byte[] signature = Encoding.UTF8.GetBytes(signatureRawData);
using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray))
{
byte[] signatureBytes = hmac.ComputeHash(signature);
string requestSignatureBase64String = Convert.ToBase64String(signatureBytes);
return string.Format("{0}:{1}:{2}:{3}", appId, requestSignatureBase64String, nonce, requestTimeStamp);
}
}
这会计算此标头:test:fhqxcZll+3ZRQi3vRexbNyoT00Yqdoyq3CrAdGQ+4kE=:715de35a4bfd4912baaa16daef21992d: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/4BOxNVNcECnaSh0cW36LiMZWVQ0DaFncY=:715de35a4bfd4912baaa16daef21992d:1521622403
在C#中我将密钥和数据转换为散列到byte[]
,这可能就是问题所在。我怎样才能在JavaScript中做同样的事情?
C#需要byte[]
作为[{1}}和HMACSHA256
中的参数。
我正在寻找一种从C#和JavaScript(Postman预请求脚本)生成相同HMACSHA256的方法
答案 0 :(得分:0)
在JS中纠正散列的解决方案是关键。在C#中我打电话:
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']));
在我使用该密钥之前,在JS中我传递了原始的base64编码值。
以下是更正前请求脚本:
loc
在我寻找解决方案的过程中,我找到了很多语言的hmac sha256实现清单:https://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/