简体   繁体   中英

How to convert this signature method from crypto (node) to crypto-js (browser)?

I have a signature method that is meant to be used in Node.js but I'd like to implement it client-side with crypto-js. It should work in latest Chrome versions.

I have tried to follow some answers like this one: Decode a Base64 String using CryptoJS

But I either get errors such as "Error: Malformed UTF-8 data", or a different result than the expected hmacDigest.

I am not sure how I could find an alternative to the "binary" digest although I found this question: How to get digest representation of CryptoJS.HmacSHA256 in JS

The method is supposed to answer the following:

"Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key"

This is the Nodejs version (with crypto):

const crypto = require('crypto')

function sign(path, params, secret) {
  const message = querystring.stringify(params)
  const secretBase64 = Buffer.from(secret, 'base64')
  const hash = crypto.createHash('sha256')
  const hmac = crypto.createHmac('sha512', secretBase64)

  const hashDigest = hash.update(params.nonce + message).digest('binary')
  const hmacDigest = hmac.update(path + hashDigest, 'binary').digest('base64')

  return hmacDigest
}

note: querystring is just an helper module that can also run in browsers: https://nodejs.org/api/querystring.html

This is my attempt (wip) at implementing with crypto-js:

import cryptojs from 'crypto-js')

function sign (path, params, secret) {
  const message = querystring.stringify(params)
  const secretParsed = cryptojs.enc.Base64.parse(secret)
  const secretDecoded = cryptojs.enc.Utf8.stringify(secretParsed) // -> this throws an error as "Error: Malformed UTF-8 data"

  const hash = cryptojs.SHA256(params.nonce + message).toString(cryptojs.enc.hex)
  const hmac = cryptojs.HmacSHA512(path + hash, secretDecoded).toString(cryptojs.enc.hex)
  return hmac
}

Try this ! I think this is what you looking for !

const crypto = require("crypto")

const sign = (path, params, secret) => {
    const message = querystring.stringify(params)
    const secret = Buffer.from(secret, 'base64')
    let sign = params.nonce + message
    let hash = crypto.createHmac('sha256', secret)
                     .update(sign)
                     .digest("base64").toString()

    let encoded = encodeURIComponent(hash)
    return encoded
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM