使用JavaScript使用HmacSHA256正确签名字符串

Obi*_*ill 4 javascript sign postman houndify

在用于身份验证的Houndify API文档中,您有以下内容块:


验证请求的示例

我们假设我们有以下信息:

UserID: ae06fcd3-6447-4356-afaa-813aa4f2ba41
    RequestID: 70aa7c25-c74f-48be-8ca8-cbf73627c05f
    Timestamp: 1418068667   
    ClientID: KFvH6Rpy3tUimL-pCUFpPg==
    ClientKey: KgMLuq-k1oCUv5bzTlKAJf_mGo0T07jTogbi6apcqLa114CCPH3rlK4c0RktY30xLEQ49MZ-C2bMyFOVQO4PyA==
Run Code Online (Sandbox Code Playgroud)
  1. 以下列格式连接UserID字符串,RequestID字符串和TimeStamp字符串: {user_id};{request_id}{timestamp}

  2. 使用示例中的值,在这种情况下,预期输出将是: ae06fcd3-6447-4356-afaa-813aa4f2ba41;70aa7c25-c74f-48be-8ca8-cbf73627c05f1418068667

  3. 使用已解码的ClientKey对消息进行签名.结果是一个32字节的二进制字符串(我们无法直观地表示).但是,在base-64编码之后,签名是:myWdEfHJ7AV8OP23v8pCH1PILL_gxH4uDOAXMi06akk=

  4. 然后,客户端生成两个身份验证标头Hound-Request-AuthenticationHound-Client-Authentication.

  5. Hound-Request-Authentication头是通过以下列格式连接UserID和RequestID组成的:{user-id};{request-id}.继续上面的示例,此标头的值为:Hound-Request-Authentication:ae06fcd3-6447-4356-afaa-813aa4f2ba41;70aa7c25-c74f-48be-8ca8-cbf73627c05f

  6. Hound-Client-Authentication标头是通过以下格式连接ClientID,TimeStamp字符串和签名组成的:{client-id};{timestamp};{signature}.继续上面的示例,此标头的值将是:Hound-Client-Authentication: KFvH6Rpy3tUimL-pCUFpPg==;1418068667;myWdEfHJ7AV8OP23v8pCH1PILL_gxH4uDOAXMi06akk=


对于Number 3,它表示"使用已解码的ClientKey对消息进行签名"."message"和"ClientKey"是两个不同的字符串.

我的问题:你如何用另一个字符串签署一个字符串,这究竟是什么意思?你会怎么用JavaScript做到这一点?

var message = 'my_message';
var key = 'signing_key';

//??what next??
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚这一切,所以我可以在Postman中创建一个预先请求脚本来做一个正确的HmacSHA256哈希.

Sam*_*Sam 7

根据文档,如果您使用其中一个SDK,它将自动验证您的请求:

SDK已经为您处理身份验证.您只需向SDK提供在创建客户端时为客户端生成的客户端ID和客户端密钥.如果您没有使用SDK,请使用右侧的代码示例生成您自己的HTTP标头以验证您的请求.

但是,如果您想手动执行此操作,我相信您需要计算他们在您的问题中的链接中描述的字符串的HMAC值,然后将其作为Hound-Client-Authentication标题的一部分发送到您的请求中.它们为node.js提供了一个示例:

var uuid = require('node-uuid');
var crypto = require('crypto');

function generateAuthHeaders (clientId, clientKey, userId, requestId) {

    if (!clientId || !clientKey) {
        throw new Error('Must provide a Client ID and a Client Key');
    }

    // Generate a unique UserId and RequestId.
    userId      = userId || uuid.v1();

    // keep track of this requestId, you will need it for the RequestInfo Object
    requestId   = requestId || uuid.v1();

    var requestData = userId + ';' + requestId;

    // keep track of this timestamp, you will need it for the RequestInfo Object
    var timestamp   = Math.floor(Date.now() / 1000),  

        unescapeBase64Url = function (key) {
            return key.replace(/-/g, '+').replace(/_/g, '/');
        },

        escapeBase64Url = function (key) {
            return key.replace(/\+/g, '-').replace(/\//g, '_');
        },

        signKey = function (clientKey, message) {
            var key = new Buffer(unescapeBase64Url(clientKey), 'base64');
            var hash = crypto.createHmac('sha256', key).update(message).digest('base64');
            return escapeBase64Url(hash);

        },

        encodedData = signKey(clientKey, requestData + timestamp),
        headers = {
            'Hound-Request-Authentication': requestData,
            'Hound-Client-Authentication': clientId + ';' + timestamp + ';' + encodedData
        };

    return headers;
};
Run Code Online (Sandbox Code Playgroud)