HMAC - C# 和 JavaScript 给出不同的结果
HMAC - C# and JavaScript give different result
我的问题与 类似,但由于问题缺少一些细节并且答案不是很有帮助,我再次提问但提供了更多细节。
我已经实施了基于 this tutorial.
的基于 HMAC 的安全性
我有可以创建正确 header 的工作 C# 应用程序(我有意设置了静态时间戳和随机数 - 仅用于测试):
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);
}
}
计算这个header:test:fhqxcZll+3ZRQi3vRexbNyoT00Yqdoyq3CrAdGQ+4kE=:715de35a4bfd4912baaa16daef21992d:1521622403
不是我正在尝试创建将生成相同 header 的 Postman pre-request 脚本。这是我的脚本:
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']));
但我得到不同的 header 值:
test:2ITrhVxr1/4BOxNVNcECnaSh0cW36LiMZWVQ0DaFncY=:715de35a4bfd4912baaa16daef21992d:1521622403
在 C# 中,我正在将键和数据转换为散列到 byte[]
,可能这就是问题所在。我怎样才能在 JavaScript 中做同样的事情?
C# 需要 byte[]
作为 HMACSHA256
和 ComputeHash
.
中的参数
我正在寻找一种从 C# 和 JavaScript(Postman pre-request 脚本)生成相同 HMACSHA256 的方法
在JS中修正hash的解决方案是关键。在 C# 中,我调用:
byte[]secretKeyByteArray = Convert.FromBase64String(apiKey);
在我使用那个密钥之前,在 JS 中我传递了原始的 base64 编码值。
这里更正了pre-request脚本:
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 实现列表:https://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/
我的问题与
我已经实施了基于 this tutorial.
的基于 HMAC 的安全性我有可以创建正确 header 的工作 C# 应用程序(我有意设置了静态时间戳和随机数 - 仅用于测试):
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);
}
}
计算这个header:test:fhqxcZll+3ZRQi3vRexbNyoT00Yqdoyq3CrAdGQ+4kE=:715de35a4bfd4912baaa16daef21992d:1521622403
不是我正在尝试创建将生成相同 header 的 Postman pre-request 脚本。这是我的脚本:
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']));
但我得到不同的 header 值:
test:2ITrhVxr1/4BOxNVNcECnaSh0cW36LiMZWVQ0DaFncY=:715de35a4bfd4912baaa16daef21992d:1521622403
在 C# 中,我正在将键和数据转换为散列到 byte[]
,可能这就是问题所在。我怎样才能在 JavaScript 中做同样的事情?
C# 需要 byte[]
作为 HMACSHA256
和 ComputeHash
.
我正在寻找一种从 C# 和 JavaScript(Postman pre-request 脚本)生成相同 HMACSHA256 的方法
在JS中修正hash的解决方案是关键。在 C# 中,我调用:
byte[]secretKeyByteArray = Convert.FromBase64String(apiKey);
在我使用那个密钥之前,在 JS 中我传递了原始的 base64 编码值。
这里更正了pre-request脚本:
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 实现列表:https://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/