创建 HMAC BodyHash Sha256 nodejs

Creating HMAC BodyHash Sha256 nodejs

我正在尝试与使用 HMAC 身份验证的服务 (paysera https://developers.paysera.com/) 集成。我已经设法集成了每个 GET 端点。然而,当涉及到 POST 请求时,代码似乎无法正常工作。

createHMACAuth(data) {
    let bodyHash = crypto.createHash('sha256').update(JSON.stringify(data)).digest('base64');
    let method = 'POST';
    let path = `/rest/v1/transfers`;
    let ts = moment().unix();
    let nonce = GUID(32);
    let port = 443;
    let macString = `${ts}\n${nonce}\n${method}\n${path}\n${host}\n${port}\n${bodyHash || ''}\n`;
    let my_mac_key = 'my_mac_key';
    let my_mac_id = 'my_mac_id';
    let mac = crypto.createHmac('sha256', my_mac_key).update(macString).digest('base64');
    let headerString = `MAC id="${my_mac_id}", ts="${ts}", nonce="${nonce}", mac="${mac}", ext="body_hash=${bodyHash}"`;
    return  headerString;
  }
  
  let data = {
    key: 'value',
    otherkey: 'othervalue'
  };
  let headers = {
      Host: 'wallet.paysera.com',
      'User-Agent': `Paysera node.js library`,
      mac_id: 'my_mac_id',
      Authorization: createHMACAuth(data);
   };

   POST_REQUEST(`${headers.host}/rest/v1/transfers`, data, headers, (err, res) => console.log(res))

我得到的回复是:

{ 
  error: 'unauthorized',
  error_description: 'Given MAC content body hash does not match actual hash of content' 
}

任何帮助将不胜感激!

我在生成 body_hash

时出错

修复

  createHMACAuth(method, path, data) {
    let bodyHash, ext;
    if (method === 'POST') {
      ext = `body_hash=${encodeURIComponent(this.createHash(JSON.stringify(data)))}`;
    }
    this.method = method;
    this.path = `/${path}`;
    let nonce = `${U.GUID(32)}`;
    let port = 443;
    let macString = `${this.ts}\n${nonce}\n${this.method}\n${this.path}\n${this.host}\n${port}\n${ext || ''}\n`;
    let mac = this.createHMACHash(macString);
    let headerString = `MAC id="${this.mac_id}", ts="${this.ts}", nonce="${nonce}", mac="${mac}"`;
    if (method === 'POST') headerString += `, ext="${ext}"`
    return  headerString;
  }

你的回答帮助我成功了。其他人可能需要的完整代码。

import crypto from 'crypto'
import fetch from 'node-fetch'

function createHash(data) {
    return crypto.createHash('sha256').update(data).digest('base64');
}

function createHMACHash (macKey, macString) {
    return crypto.createHmac('sha256', macKey).update(macString).digest('base64');
}

async function createHMACAuth() {
    const macId = 'your-mac-id';
    const macKey = 'your-mac-key';

    const ts = new Date().getTime();
    const nonce = 'nQnNaSNyubfPErjRO55yaaEYo9YZfKYU';
    const method = 'POST';
    const uri = '/rest/v1/transaction'
    const host = 'wallet.paysera.com'
    const port = 443;
    const data = {
        "payments": [
            {
                "description": "Payment for order No. 1234",
                "price": 1299,
                "currency": "EUR",
                "parameters": {
                    "orderid": 1234
                }
            }
        ],
        "redirect_uri": "http://www.example.com/somePage"
    }

    let ext;
    if (method === 'POST') {
        ext = `body_hash=${encodeURIComponent(createHash(JSON.stringify(data)))}`;
    }
    let macString = `${ts}\n${nonce}\n${method}\n${uri}\n${host}\n${port}\n${ext || ''}\n`;
    let mac = createHMACHash(macKey, macString);
    let headerString = `MAC id="${macId}", ts="${ts}", nonce="${nonce}", mac="${mac}"`;
    if (method === 'POST') headerString += `, ext="${ext}"`

    const response = await fetch(`https://${host}${uri}`,{
        method:method,
        headers:{
            Authorization: headerString,
            'Content-Type':'application/json'
        },
        body: JSON.stringify(data)
    })

    return headerString;
}

await createHMACAuth()