Ruby 与 Go / sha256 hmac base64 编码字符串不匹配
Ruby vs. Go / sha256 hmac base64 encoded string mismatches
玩弄虚构,我正在尝试创建一个 ruby 客户端。
出于安全原因,我需要签署 url
这是 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 部分完全不了解的结果,但让我们详细说明问题)
如何才能使两个版本的输出相同?为什么我们在这些语言之间得到接近但不准确的结果?
非常感谢您的回复
Go 代码使用 base64 编码的 URL 安全变体,而您的 Ruby 代码使用普通版本。 URL 安全版本使用 -
和 _
而不是 +
和 /
,因此在 URL 中使用是安全的。 Ruby 版本还包括填充(末尾的 =
)。
您可以使用 URL safe version in Ruby,也可以指定不填充以获得与 Go 相同的结果:
Base64.urlsafe_encode64(hmac, false)
玩弄虚构,我正在尝试创建一个 ruby 客户端。
出于安全原因,我需要签署 url
这是 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 部分完全不了解的结果,但让我们详细说明问题)
如何才能使两个版本的输出相同?为什么我们在这些语言之间得到接近但不准确的结果?
非常感谢您的回复
Go 代码使用 base64 编码的 URL 安全变体,而您的 Ruby 代码使用普通版本。 URL 安全版本使用 -
和 _
而不是 +
和 /
,因此在 URL 中使用是安全的。 Ruby 版本还包括填充(末尾的 =
)。
您可以使用 URL safe version in Ruby,也可以指定不填充以获得与 Go 相同的结果:
Base64.urlsafe_encode64(hmac, false)