【问题标题】:Ruby vs. Go / sha256 hmac base64 encoded string mismatchesRuby vs. Go / sha256 hmac base64 编码字符串不匹配
【发布时间】:2020-11-06 13:13:07
【问题描述】:

玩弄想象,我正在尝试创建一个 ruby​​ 客户端。

出于安全原因,我需要对网址进行签名

这是 go 提供的示例:

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)
}

转换为 ruby​​,这给了我们:

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=

使用 ruby​​,无论做什么,都会以 = 结束

虽然 go 使用下划线,但 ruby​​ 使用反斜杠(这最后一个语句可能是完全不了解特定 ruby​​ 部分的结果,但让我们详细说明一下问题)

应该怎样做才能在两个版本中获得相同的输出?为什么我们会在这些语言之间得到接近但不准确的结果?

非常感谢您的回复

【问题讨论】:

    标签: ruby go openssl base64 hmac


    【解决方案1】:

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

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

    Base64.urlsafe_encode64(hmac, false)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-03
      • 1970-01-01
      • 2018-12-28
      • 2021-05-26
      • 2018-06-12
      • 2020-10-18
      • 2021-07-10
      • 1970-01-01
      相关资源
      最近更新 更多