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

Ben*_*Ben 3 ruby base64 openssl go hmac

我正在尝试创建一个红宝石客户端。

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

这是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)
}
Run Code Online (Sandbox Code Playgroud)

转换为红宝石,这使我们:

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)
Run Code Online (Sandbox Code Playgroud)

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

wClkWcUvI9ILs7noAr_HtnKpRCeeWBXE1Ne2C99sAco

我得到以下与红宝石版本:

wClkWcUvI9ILs7noAr/HtnKpRCeeWBXE1Ne2C99sAco=

使用红宝石,无论做什么,最终都会导致 =

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

如何获得两个版本的相同输出?为什么我们在这些语言之间得到接近但不准确的结果?

非常感谢您的回复

mat*_*att 7

The Go code uses the URL safe variant of base64 encoding where your Ruby code uses the normal version. The URL safe version uses - and _ instead of + and / so that it is safe for use in URLs. The Ruby version also includes padding (the = at the end).

You can use the URL safe version in Ruby, and you can also specify no padding to get the same result as Go:

Base64.urlsafe_encode64(hmac, false)
Run Code Online (Sandbox Code Playgroud)