Search code examples
pythongoencryptionrsapublic-key-encryption

RSA Encryption/Decryption between Python and Golang not working?


When I encrypt a string with Go, I am unable to decrypt it again with Python. I'm clearly doing something wrong, but I'm unable to identify the problem. Any assistance greatly appreciated.

Essentially, I'm encrypting a string with the following function (which I'm then able to decrypt with Go, but not Python):

func encryptString(s string) string {
    publicKey, _ := os.ReadFile("public.pem")
    block, _ := pem.Decode([]byte(publicKey))
    if block.Type != "PUBLIC KEY" {
        log.Fatal("error decoding public key from pem")
    }
    parsedKey, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        log.Fatal("error parsing key")
    }
    var ok bool
    var pubkey *rsa.PublicKey
    if pubkey, ok = parsedKey.(*rsa.PublicKey); !ok {
        log.Fatal("unable to parse public key")
    }
    rng := rand.Reader
    ciphertext, err := rsa.EncryptOAEP(sha256.New(), rng, pubkey, []byte(s), nil)
    if err != nil {
        log.Fatal(err)
    }
    return base64.StdEncoding.EncodeToString(ciphertext)
}

This is the python code I'm using to try and decode the encrypted string:

import os
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.padding import MGF1, OAEP
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.serialization import load_pem_private_key

encrypted_message = "<REMOVED>"
encrypted_message_bytes = base64.b64decode(encrypted_message.encode("utf-8"))
PRIVATE_KEY = os.getenv("PRIVATE_KEY")
private_key_bytes = PRIVATE_KEY.encode("utf-8")
private_key: RSAPrivateKey = load_pem_private_key(private_key_bytes, None)
padding = OAEP(mgf=MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)
decrypted_message = private_key.decrypt(encrypted_message_bytes, padding)
print(decrypted_message)

On running this, I just get the following error:

Traceback (most recent call last):
  File "decrypt_test.py", line 14, in <module>
    decrypted_message = private_key.decrypt(encrypted_message_bytes, padding)
  File "venv/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 424, in decrypt
    return _enc_dec_rsa(self._backend, self, ciphertext, padding)
  File "venv/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 87, in _enc_dec_rsa
    return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
  File "venv/lib/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 151, in _enc_dec_rsa_pkey_ctx
    raise ValueError("Encryption/decryption failed.")
ValueError: Encryption/decryption failed.

I don't have any control over the python code in production, so I would like to only make changes to Go code. I also have the same problem the other way around, but I expect it's the same issue.

Any thoughts greatly appreciated.


Solution

  • I'm not entirely sure what changed, but when I revisited this, it did start working. I did change the way I was loading the certificate files etc. and so there may have been an issue there with mismatched keys or something like that as suggested here. I can confirm performing encryption/decryption between python/Go does work. Thanks to those that responded.