Ruby与Go / sha256 hmac base64编码的字符串不匹配

时间:2019-06-12 09:44:37

标签: ruby go openssl base64 hmac

随心所欲,我正在尝试创建一个ruby客户。

出于安全原因,我需要在网址上签名

以下是提供的示例:

package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
)

func main() {
  signKey := "ea79b7fd-287b-4ffe-b941-bf983181783f"
  urlPath := "/resize"
  url := "https%3A%2F%2Fxyz"
  urlQuery := "nocrop=true&type=jpeg&url=" + url + "&width=500"

  h := hmac.New(sha256.New, []byte(signKey))
  h.Write([]byte(urlPath))
  h.Write([]byte(urlQuery))
  buf := h.Sum(nil)
    fmt.Println(base64.RawURLEncoding.EncodeToString(buf)
}

转换为红宝石,这给了我们:

require 'openssl'
require 'base64'

signKey = "ea79b7fd-287b-4ffe-b941-bf983181783f"
urlPath = "/resize"
url = "https%3A%2F%2Fxyz"
urlQuery = "nocrop=true&type=jpeg&url=" + url + "&width=500"

digest = OpenSSL::Digest.new('sha256')
hmac = OpenSSL::HMAC.digest(digest, signKey, "#{urlPath}#{urlQuery}")
pp Base64.strict_encode64(hmac)

我们快到了,但是有一个小问题,不知道这是由于openssl还是base64引起的,但是例如,当我通过go获得此信息时:

wClkWcUvI9ILs7noAr_HtnKpRCeeWBXE1Ne2C99sAco

我在Ruby版本中得到以下信息:

wClkWcUvI9ILs7noAr/HtnKpRCeeWBXE1Ne2C99sAco=

使用红宝石,无论做什么,都以=

结尾

当go使用下划线时,ruby使用反斜杠(这最后一个陈述可能是由于对特定的ruby部件完全不了解的结果,但我们只详细说明问题)

如何在两个版本上获得相同的输出?为什么我们会在两种语言之间得到接近但不完全相同的结果?

非常感谢您的答复

1 个答案:

答案 0 :(得分:7)

Go代码使用base64编码的URL安全变体,而Ruby代码使用普通版本。 URL安全版本使用-_而不是+/,因此可以安全地在URL中使用。 Ruby版本还包括填充(末尾的=)。

您可以使用URL safe version in Ruby,也可以不指定填充值来获得与Go相同的结果:

Base64.urlsafe_encode64(hmac, false)