[=Ga=] Ras public 密钥加密到 galang

Ruby RSA public key encryption to Golang

我目前正在做一个项目,我必须 "convert" 从 Ruby(版本 1.9.3p194)到 Golang(版本 1.7)的一些代码。这部分 Ruby 使用 RSA public 密钥加密,每次执行时我总是得到一致的结果。这是使用的函数:

编辑:我忽略了public密钥加密后,还有一个base 64编码

public_key = OpenSSL::PKey::RSA.new(public_encryption_key)
public_encrypted_text = public_key.public_encrypt(text, OpenSSL::PKey::RSA::NO_PADDING)
base64_encrypted_text = Base64.encode64(public_encrypted_text).gsub("\n", "")
escaped_encrypted_text = URI.escape(encrypted_key, "/+=")

但是在 Golang 中,由于 rsa 库,我无法获得一致的结果,因为加密函数采用随机参数每次生成不同的结果。我明白为什么它每次都需要不同,但我无法获得与 ruby 生成的内容类似的任何内容。这些是 Golang 中使用的函数:

//keyBytes is the public key as []byte
block, _ := pem.Decode(keyBytes)
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
    return nil, err
}

pubKey, ok := key.(*rsa.PublicKey)
if !ok {
    return nil, errors.New("Cannot convert to rsa.PublicKey")
}

result, err := rsa.EncryptPKCS1v15(cryptorand.Reader, pubKey, text)
encryptedText := base64.URLEncoding.EncodeToString(result)
encryptedText = strings.TrimRight(encryptedText, "=")

其中一个问题是 ruby 可以毫无问题地加密文本,而在 golang 中,我收到一个错误消息,提示密钥太短,无法加密所有内容。

如果我加密其他东西,比如 "Hello"。解密时,我从 ruby 得到错误 "padding check failed"。解密处理如下:

private_key.private_decrypt(Base64.decode64(text))  

编辑: 感谢 gusto2 的回答,我现在更清楚发生了什么,因为我对 RSA 了解不多。

现在在 Golang 中,我能够使用 PKCS1 v1.5 加密文本,只是为了确保我也尝试解密它,同样在 Golang 中,没有问题。

然而在Ruby我仍然无法使用私钥解密。所以我认为 Golang 中使用的 base64 编码是问题所在。所以我将该部分更改为:

encryptedText := base64.StdEncoding.EncodeToString(result)

我还删除了最后一行,因为等号被修剪了。

完成后,它就像一个魅力。

我对golang一无所知,但我对RSA可能有所了解。

区别似乎在于 padding

对于 ruby - 不使用填充
对于 golang - 使用 PKCS1v15 填充

ruby 示例中,您使用 OpenSSL::PKey::RSA::NO_PADDING 非常非常不安全。它被称为 textbook RSA 并且在现实生活中并不适用,因为它有很多弱点和危险的陷阱。因此 ruby 示例非常危险不安全 因为使用了教科书 RSA。它也仅限于加密小消息(比密钥空间小得多)。

RSA 使用了两种填充类型:

  • PKCS1 v1(通常称为 PKCS1)- 这是确定性填充(输出始终相同),许多密码学家认为此选项已过时,因为在未正确使用时发现了一些弱点,但它仍在使用中,并未被视为损坏。

  • PKCS1 v2(通常称为 OAEP 或 PSS)是随机(随机化)填充。您可以区分最后两个,因为 OAEP 的输出总是不同的。

One of the problems is that ruby can encrypt the text with no problem, and in golang I'm getting an error that the key is too short to encrypt everything

您只提供了 golang 示例的一小部分,所以这里我可能只假设很多事情

正如您声称 golang 示例输出随机输出并根据使用的参数 PKCS1 v1.5,我假设该实现正在执行 hybrid encryption 这是一种很好且更安全的数据加密方式RSA(使用带有随机密钥的对称加密和 wrap/encrypt 带有 RSA 的密钥)。