如何将此JS签名生成器功能转换为Ruby?

时间:2019-09-27 16:17:42

标签: javascript ruby sha256 hmac

我正在尝试将Zoom SDK集成到我的应用程序中,但是我很难弄清楚如何将其示例代码转换为将签名生成为ruby。

示例代码-

const base64JS = require('js-base64');
const hmacSha256 = require('crypto-js/hmac-sha256');
const encBase64 = require('crypto-js/enc-base64');

function generateSignature(data) {
    let signature = '';
    const ts = new Date().getTime();
    const msg = base64JS.Base64.encode(data.apiKey + data.meetingNumber + ts + data.role);
    const hash = hmacSha256(msg, data.apiSecret);
    signature = base64JS.Base64.encodeURI(`${data.apiKey}.${data.meetingNumber}.${ts}.${data.role}.${encBase64.stringify(hash)}`);
    return signature;
}

const data = {apiKey: "" ,
apiSecret: "",
meetingNumber: 888,
role: 0}

console.log(generateSignature(data));

generateSignature函数在红宝石中的外观如何?

我尝试了几次,但是当我尝试用Ruby编写时,输出的签名有所不同。我怀疑我编码和解码不正确。

这是上面的javascript代码,我对其进行了少许修改以进行交叉引用

const base64JS = require('js-base64');
const hmacSha256 = require('crypto-js/hmac-sha256');
const encBase64 = require('crypto-js/enc-base64');

function generateSignature(data) {
  let signature = '';
  const ts = "1569600658561"
  const msg = base64JS.Base64.encode(data.apiKey + data.meetingNumber + ts + data.role);

  console.log(msg); // This matches the ruby

  const hash = hmacSha256(msg, data.apiSecret);
  signature = base64JS.Base64.encodeURI(`${data.apiKey}.${data.meetingNumber}.${ts}.${data.role}.${encBase64.stringify(hash)}`);
  return signature;
}

data = {
  apiKey: 'api_key',
  apiSecret: 'secret',
  meetingNumber: '1000',
  role: '0'
}


console.log(generateSignature(data));

这是我对红宝石的尝试

class ZoomSignatureGenerator

  def self.generate
    data = {
      api_key: 'api_key',
      api_secret: 'secret',
      meeting_number: '1000',
      role: '0'
    }

    ts = "1569600658561"
    msg = Base64.encode64(data[:api_key] + data[:meeting_number] + ts + data[:role]);
    puts(msg)
    hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), data[:api_secret], msg)
    signature = Base64.urlsafe_encode64("#{data[:api_key]}.#{data[:meeting_number]}.#{ts}.#{data[:role]}.#{Base64.encode64(hash)}");
    return signature
  end
end

我希望它们是相同的输出。但是他们最终变得与众不同。

希望有人可以帮助我:)

2 个答案:

答案 0 :(得分:3)

Base64.encode64(value)的输出以换行符分隔,使用Base64.strict_encode64(value)生成与Node.js相同的结果。

require "base64"
require "openssl"

def generate_signature(api_key, api_secrete, meeting_number, role)
  timestamp = 1544683367752

  message = Base64.strict_encode64("#{api_key}#{meeting_number}#{timestamp}#{role}")

  hash = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', api_secrete, message))

  signature = Base64.strict_encode64("#{api_key}.#{meeting_number}.#{timestamp}.#{role}.#{hash}")
end

generate_signature("key", "secret", 123456, 0)

答案 1 :(得分:1)

遇到相同的问题,显然Zoom使用base 64编码的二进制字符串,因此请尝试使用

而不是使用HMAC.hexdigest
hmac = OpenSSL::HMAC.new(API_KEY, 'sha256')
hmac << data
hash = Base64.encode64(hmac.digest)

digest方法以二进制字符串形式返回身份验证代码, hexdigest以十六进制编码的字符串返回身份验证代码