首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Javascript进行Base64编码的HMAC散列

用Javascript进行Base64编码的HMAC散列
EN

Stack Overflow用户
提问于 2018-05-31 02:56:57
回答 1查看 4.4K关注 0票数 0

我正在使用Payeezy API来处理一个webapp上的付款,他们购买的API需要一个使用api机密签名的有效载荷的HMAC。从文档中摘录:

通过按如下所示的顺序追加下面的参数来构造数据param。开发人员的每个key - API密钥。安全随机数。c.时间戳--以毫秒为单位的划时代时间戳。令牌-商人令牌。有效载荷-作为post请求传递的实际主体内容。使用下面的键计算上述数据参数上的HMAC SHA256哈希,为给定的apiSecret密钥计算apiSecret消费秘密令牌,计算哈希的base64,这将是我们需要的授权头值。

我在NPM上找到了一个名为jshashes的库,我试图使用它们的库来散列我的头params,我的代码如下所示:

代码语言:javascript
复制
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)

与示例哈希值相比的结果如下:

代码语言:javascript
复制
//mine
beWtpCGDv/iBoAUDAThGFXIge9eli/Xtl7JIBuR1bd4= 


//payeezy sample 
NmUzMTNmYWU0YjExM2UxMmM0NjllZGI1NThjY2M5MmUzMzE3NTFlZmQ1NDQxYzAzMTgwMmIwNDQ0MWVmYTdhMw== 

从字符计数的外观看,我可以看出我的散列过程是不正确的,但我不知道哪里出了问题。

我在这里看到过类似的问题,但没有人回答,任何帮助都是值得感谢的。

此外,我在Node.js上尝试了密码库:

代码语言:javascript
复制
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之后,它最终返回了一个字符串,该字符串看起来与示例的字符长度相同,但是验证仍然没有通过.

EN

回答 1

Stack Overflow用户

发布于 2018-05-31 03:35:12

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

代码语言:javascript
复制
console.log(atob('NmUzMTNmYWU0YjExM2UxMmM0NjllZGI1NThjY2M5MmUzMzE3NTFlZmQ1NDQxYzAzMTgwMmIwNDQ0MWVmYTdhMw=='))

你会得到

代码语言:javascript
复制
6e313fae4b113e12c469edb558ccc92e331751efd5441c031802b04441efa7a3

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

所以我的猜测是,他们得到了十六进制字符串HMAC,和base64编码-这似乎是非常愚蠢的,十六进制是安全的发送,为什么使它4/3 3rds大!

如果他们只是使用base64的HMAC,它将只有45个字符长!

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

所以,您的代码应该做同样的事情。

喜欢

代码语言:javascript
复制
Data = Buffer.from(sha256.hex_hmac(apiSecret, data), 'utf-8').toString('base64');

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

最后,https://developer.payeezy.com/payeezy-api/apis/post/transactions-3**) (实际上这一点只是为了“匹配”示例页面上由OP 链接的授权计算方式,因此,没有必要无缘无故地使有效负载更大)**

另一点您需要知道,有效载荷JSON需要以一种特定的格式,它似乎.2空格缩进…再说一次,这是对带宽的愚蠢浪费。{"key":1234}需要12个字符

代码语言:javascript
复制
{
  "key": 1234
}

花了17

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

代码语言:javascript
复制
JSON.stringify(payload,null, 2)

这是拼图的最后一部分,您的代码如下所示

代码语言:javascript
复制
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');
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50615993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档