I'm currently working on a project where I have to "convert" some code from Ruby(version 1.9.3p194) to Golang(version 1.7). There is this part where Ruby uses RSA public key encryption and I always get a consistent result every time it gets executed. This is the function used:
Edit: I overlooked that after the public key encryption, there is a base 64 encoding as well
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, "/+=")
However in Golang, due to the rsa library I can't get a consistent result since the function to encrypt takes a random parameter to generate different result each time. I understand why it needs to be different every time, but i can't get anything remotely similar to what ruby generates. These are the functions used in 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, "=")
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.
If I encrypt something else, like "Hello". When decrypting I get from ruby the error "padding check failed". The decryption is being handle like follows:
private_key.private_decrypt(Base64.decode64(text))
EDIT: Thanks to the answer of gusto2 I now know better what is going on since I didn't have much understanding of RSA.
Now in Golang I was able to encrypt the text using PKCS1 v1.5, and just to be sure I tried to decrypt that as well, also in Golang, with no problem.
However in Ruby I still wasn't able to decrypt using the private key. So I figured that the base64 encoding used in Golang was the issue. So I changed that part to this:
encryptedText := base64.StdEncoding.EncodeToString(result)
And also I removed the last line were the equal sign was being trimmed.
With that done it worked like a charm.