关于go:Ruby RSA对Golang的公钥加密

Ruby RSA public key encryption to Golang

我目前正在做一个项目,在这个项目中,我必须将一些代码从Ruby(1.9.3P194版本)转换为Golang(1.7版本)。在Ruby使用RSA公钥加密的部分中,每次执行它时,我总是得到一致的结果。这是使用的功能:

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

1
2
3
4
5
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("
"
,"")
escaped_encrypted_text = URI.escape(encrypted_key,"/+=")

然而,在golang中,由于RSA库的存在,我无法得到一致的结果,因为要加密的函数每次都使用一个随机参数来生成不同的结果。我理解为什么每次都需要不同,但我不能得到任何和Ruby生成的东西类似的东西。以下是Golang中使用的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//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中,我得到一个错误,即密钥太短,无法加密所有内容。

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

1
private_key.private_decrypt(Base64.decode64(text))

编辑:多亏了古斯塔2的回答,我现在更清楚发生了什么,因为我对RSA没有太多了解。

现在在Golang,我可以使用pkcs1 v1.5对文本进行加密,只是为了确保我也能解密它,在Golang,没有问题。

但是在Ruby中,我仍然无法使用私钥解密。所以我认为Golang中使用的base64编码是问题所在。所以我把这部分改成了:

1
encryptedText := base64.StdEncoding.EncodeToString(result)

我也删除了最后一行的等号被修剪。

这样一来,它就像一个魅力。


我对Golang不太了解,但是我可能对RSA有所了解。

差别似乎在填充物上。

对于Ruby-不使用填充
对于Golang-使用pkcs1v15填充

在rubye示例中,使用OpenSSL::PKey::RSA::NO_PADDING,这是非常不安全的。它被称为教科书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使用,我假设该实现正在进行混合加密,这是用rsa加密数据的一种好的、更安全的方法(使用随机密钥的对称加密和用rsa包装/加密密钥)。