我目前正在开发一个项目,我必须将一些代码从Ruby(版本1.9.3p194)“转换”为Golang(版本1.7)。这部分Ruby使用RSA公钥加密,每次执行时我总能得到一致的结果。这是使用的功能:
编辑:我忽略了在公钥加密之后,还有一个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中,我收到的错误是密钥太短而无法加密所有内容。
如果我加密其他内容,比如“你好”。解密时我从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。
对于红宝石 - 不使用填充物 对于golang - 使用PKCS1v15填充
在rubyexample你使用OpenSSL::PKey::RSA::NO_PADDING
是非常非常不安全的。它被称为教科书RSA,并不打算在现实生活中使用,因为它有许多弱点和危险的陷阱。因此,由于使用了教科书RSA,因此ruby示例非常危险。它也仅限于加密小消息(比密钥空间小得多)。
RSA使用两种填充类型:
其中一个问题是ruby可以毫无问题地对文本进行加密,而在golang中我收到的错误是密钥太短而无法加密所有内容
你只提供了golang示例的一小部分,所以在这里我可能只假设很多东西。
正如您声称golang示例输出随机输出并根据参数PKCS1 v1.5使用,我假设实现正在执行hybrid encryption,这是使用RSA加密数据的良好且更安全的方式(使用随机密钥的对称加密和用RSA包装/加密密钥。