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部分完全不了解的结果,但我们仅详细说明问题)
如何获得两个版本的相同输出?为什么我们在这些语言之间得到接近但不准确的结果?
非常感谢您的回复
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)