使用Javascript

时间:2018-05-31 02:56:57

标签: javascript hash sha256 hmac payeezy

我正在使用Payeezy API来处理webapp上的付款,他们购买的API需要使用api secret签署的有效负载HMAC。摘自文档:

  

通过以与所示顺序相同的顺序附加以下参数来构造数据参数。一个。 apikey - 开发人员的API密钥。湾随机数 - 安全随机数。 C。 timestamp - 纪元时间戳,以毫秒为单位。 d。令牌 - 商家令牌。即payload - 作为post请求传递的实际正文内容。使用f下面的密钥在上面的数据参数上计算HMAC SHA256哈希值。 apiSecret - 给定api密钥的Consumer Secret令牌计算哈希的base64,这将是我们所需的授权头值。

我在NPM上找到了一个名为jshashes的库,我试图使用他们的库来标记我的标题参数,我的代码看起来像这样:

const payload = {
        "merchant_ref": "1-Sale",
        "transaction_type": "purchase",
        "method": "credit_card",
        "amount": amount * 100,
        "partial_redemption": "false",
        "currency_code": "USD",
        "credit_card": {
          "type": type,
          "cardholder_name": cardholder_name,
          "card_number": card_number,
          "exp_date": exp_date,
          "cvv": cvv
        }
      }
      const data = apikey + nounce + timestamp + token + JSON.stringify(payload)
      const sha256 = new Hashes.SHA256()
      const shaData = sha256.b64_hmac(apiSecret, data)

与样本散列值相比的结果如下:

//mine
beWtpCGDv/iBoAUDAThGFXIge9eli/Xtl7JIBuR1bd4= 


//payeezy sample 
NmUzMTNmYWU0YjExM2UxMmM0NjllZGI1NThjY2M5MmUzMzE3NTFlZmQ1NDQxYzAzMTgwMmIwNDQ0MWVmYTdhMw== 

从字符计数的外观我可以看出我的哈希过程不正确但我无法弄清楚哪里出错了。

我在这里看到过类似的问题,但没有人回答,任何帮助都表示赞赏。

另外,我在Node.js上尝试了加密库:

const data = apikey + nounce + timestamp + token + JSON.stringify(payload)

  const hmac = crypto.createHmac('sha512', apiSecret)

  hmac.on('readable', () => {
    const data = hmac.read()
    if (data) {
      console.log(data.toString('base64'));
    }
  })

  hmac.write(data)
  hmac.end()

相同的结果,与样本散列值相比,字符长度只有一半

更新:在我对数据使用SHA512之后,它最终返回了一个字符串,该字符串看起来与样本具有相同的字符长度,但验证仍未通过......

1 个答案:

答案 0 :(得分:1)

如果将base64示例从该站点转换为字符串



console.log(atob('NmUzMTNmYWU0YjExM2UxMmM0NjllZGI1NThjY2M5MmUzMzE3NTFlZmQ1NDQxYzAzMTgwMmIwNDQ0MWVmYTdhMw=='))




你得到了

6e313fae4b113e12c469edb558ccc92e331751efd5441c031802b04441efa7a3

这是一个64个字符(256位)的十六进制字符串

所以我的猜测是他们得到十六进制字符串HMAC,并且base64编码 - 这看起来非常愚蠢,十六进制是安全的发送原因,为什么使它4 / 3rds更大!!

如果他们只是使用了HMAC的base64,那么它只有45个字符!!

相反,他们得到64个字符的十六进制字符串和base64编码,以获得88个字符!奇怪的设计决定!!

所以,你的代码应该做同样的

Data = Buffer.from(sha256.hex_hmac(apiSecret, data), 'utf-8').toString('base64');

不确定在节点中是否有更好的方法将十六进制编码的字符串转换为base64,但是可行的

最后(实际上这一点只是#34;匹配"如何在OP https://developer.payeezy.com/payeezy-api/apis/post/transactions-3链接的示例页面上计算授权)所以,它是' s没有必要无缘无故地增加有效载荷)

你需要知道的另一点是,有效载荷JSON需要采用特定的格式...... 2空间缩进...再次,这是一个愚蠢的带宽浪费.. {"key":1234}需要12人物

{
  "key": 1234
}

需要17

所以,无论如何,你需要这样做:

JSON.stringify(payload,null, 2)

最后一部分拼图应该使你的代码如下

const data = apikey + nonce + timestamp + token + JSON.stringify(payload,null, 2)
const sha256 = new Hashes.SHA256()
const shaData = Buffer.from(sha256.hex_hmac(secret, data), 'utf-8').toString('base64');