随心所欲,我正在尝试创建一个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部件完全不了解的结果,但我们只详细说明问题)
如何在两个版本上获得相同的输出?为什么我们会在两种语言之间得到接近但不完全相同的结果?
非常感谢您的答复
答案 0 :(得分:7)
Go代码使用base64编码的URL安全变体,而Ruby代码使用普通版本。 URL安全版本使用-
和_
而不是+
和/
,因此可以安全地在URL中使用。 Ruby版本还包括填充(末尾的=
)。
您可以使用URL safe version in Ruby,也可以不指定填充值来获得与Go相同的结果:
Base64.urlsafe_encode64(hmac, false)