[image] aeros: Was this intended to be “Don’t try to use a public RSA key to decrypt ”? Yes, or rather, don’t try to use a private RSA key to encrypt. Or both. :slight_smile: I’ve corrected the post, thanks for pointing that out! Answer from mjpieters on discuss.python.org
Top answer
1 of 2
7

That is totally insecure, because you are using raw RSA without padding.

Your application needs a signature, so you should not be dealing with encryptions and decryptions. For instance, PKCS#1 v1.5 is a good protocol, even though the signature is a piece of data that must be appended to what you want to prove the authenticity of.

To verify a PKCS#1 v1.5 signature in Python, you do:

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA

rsa_key = RSA.importKey(open(verification_key_file, "rb").read())
verifier = PKCS1_v1_5.new(rsa_key)
h = SHA.new(data_to_verify)
if verifier.verify(h, signature_received_with_the_data):
    print "OK"
else:
    print "Invalid"

I would strongly recommend to change the PHP code so that it creates such a signature.

2 of 2
0

Your function is correct. You just need to be giving it the path to your private key in order to decrypt instead of your public key. The public key is for encrypting, the private key is for decrypting.

def _decrypt_rsa(decrypt_key_file, cipher_text):
    '''
    Decrypt RSA encrypted package with private key
    :param decrypt_key_file: Private key
    :param cipher_text: Base64 encoded string to decrypt
    :return: String decrypted
    '''
    from Crypto.PublicKey import RSA
    from base64 import b64decode

    key = open(decrypt_key_file, "r").read()
    rsakey = RSA.importKey(key)
    #optionally could use OAEP
    #from Crypto.Cipher import PKCS1_OAEP
    #rsakey = PKCS1_OAEP.new(rsakey)
    raw_cipher_data = b64decode(cipher_text)
    decrypted = rsakey.decrypt(raw_cipher_data)
    return decrypted
Discussions

cryptography - Python Decryption using private key - Stack Overflow
1 How to decrypt Windows EC2 instance password that was encrypted with a PEM RSA private key using Python? More on stackoverflow.com
🌐 stackoverflow.com
September 18, 2016
How can I encrypt with a RSA private key in python? - Stack Overflow
Is it possible to encrypt a message with a private key in python using pycryptodome or any other library? I know that you are not supposed to encrypt with the private key and decrypt with the publi... More on stackoverflow.com
🌐 stackoverflow.com
Cannot decrypt file using RSA private key and Cryptography Package
In the end, man openssl-rsautl explained that the default padding type assumed by openssl is PKCS1v15. It was then easily fixed by updating the padding: decrypted_data = private_key.decrypt( ky2, padding.PKCS15.1() ) I'm sorry to say that the Cryptography documentation is just a bit inaccessible for me and has taken days to work this out with the help of ChatGPT. I would encourage others to use Perl's Crypt modules over Python where possible as the documentation is a lot more accessible. More on reddit.com
🌐 r/learnpython
1
2
December 24, 2023
RSA decryption using just the private exponent and the public key
I believe it should be as easy as: cipherText^d mod N More on reddit.com
🌐 r/crypto
16
5
June 17, 2019
Top answer
1 of 2
1

There are a few problems already noted in the comments by @Topaco:

Apart from the incorrect key import, the wrong padding is used. The PyCryptodome counterpart to RSA/ECB/PKCS1Padding is PKCS1_v1_5 (and not PKCS1_OAEP). Second, the ciphertext is apparently corrupted: The posted (and thus compromised) private key has a length of 2048 bits = 256 bytes, i.e. the ciphertext must be of the same length. But the posted (Base64 decoded) ciphertext is 380 bytes long (len(by)). Furthermore, in decrypt() not str(by) but by must be passed.

You also have a typo in Pkey, the Base64 encoded body is ...boc61 and not ...boc6 (i.e. the last character is missing). If this is fixed, the key can be imported with RSA.importKey(base64.b64decode(Pkey))

When those are addressed we see that s, after base64 decoding, is too long to be the result of RSA encryption with a 2048 bit modulus. However by trying all offsets into the base64-decoded s and taking the next 256 bytes we get a successful decrypt at offset 3.

# https://stackoverflow.com/q/74840474/238704
import base64

from Cryptodome.Cipher import PKCS1_v1_5
from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes

private_key_pem = '''-----BEGIN RSA PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCTiP1x58DboFjS
4WgzMm8tuY9VoHwANbOHNuuiElsZ4xIVFS+ZG7lu7Iz9gzmsno/YiqQXms8hXmUH
ouGgVJLJGPTw/NXAnLq6XlwB3C+zQMWpxvcMub4D6/IltP/PUpKNj9QzKKGhZF+6
s5B/QBzmSeNYlYYyGnO9GxyuHyR7P5xqF9AcpSskn9gjYy0koTLmvg/bwFx6jnci
np2qVHo5CFvSTAgrZKBCmKD2c2AGD9O+TSOrT0RDzvJosW4P1QJ9qsCjKFSPW/8K
IvB+AsSA+9xiVMDm/3YABBBM/R7wDcciTmKucZoEuDeWJg+cwLur8kKSVNwwkwCT
MqTIbHn5AgMBAAECggEABl5aemlDpPdl/ixmwBcEP5gL/OlBkQzAZCzVvRhHwHVR
2YEhnd1ZgtVJPMRGYBI0KWfKr44qNMmLWOoKDU65S179a82uOHNLiDH8jMQBdx5r
qemBzpXSAv9TY5dNl5h75Qp5YX/2gi4AB+IqcaPF25cC7lb+BPmpV1dtRILpozxJ
78mE0o0ddAJhg+0lIX6lZqjXbKJh4uiIqJIwezOM/B9U59qWEiJoHurkJIQoc00n
lp+XKUJfUWE5OHdy2DZNbAWEDqvFiD3DBd5baks/CPHy6IZLj7e5y+h/b65veDw6
MWpwXK30vroRmIzfNFcbONuQ3EjHBvCXzQYppUPnAQKBgQDD/k9NVQ8r2EnhjX0g
dQKobT7aCpY/y0QvDZ6aeuOVkfqnFB+rUUSf5WsXbANghqsHtzJa+cDUpP0C1PuE
hexGS+SsLywKI/33S014tvt5iF/MgEu08sLHtoxR/dH3H4k2LDGMNBrKILFnfDYP
40e3QKdogXMsEw4C0tb85YGrIQKBgQDAtJZp+onH0NSDXL0kbWZa8GFuVMGjTz2m
6E+j3NHK5GDGSAme755lDS61TTz2xNYaJFEwUdvYKQq1x/Q7jffKMPcHUJ5uy7bH
QjFho377rvN9bNSk+UdP8AkhvjaLNC0c5K5eNEUgumrd+yDLw2YNvjOe/RjE3QiW
zpGHLigL2QKBgQC2LUufMSJB+fBqlG6rXbgTwD/8wnx4XcNKDVnQc8vZenBHH0B0
qLyl98S8Z60X6vVM3a8TuzTPM3DuUfRccXN2wBKVLd+8qUnmtHsVatiDVgzd9J7q
WgBNTNRPXiPtlcWfsiJ4FPKV0R+1dlJ2ICfIIXO6gyD/5dJPM5WcSuRloQKBgQCq
Tu+gOgwKzEUE07FVwFn1hPyWxdFcw2t5V1cLOt0usyfUFVZrYNpb9IqTMO/wJ4YR
FIesbKwfHiaZAV6YQ5/60cuAa3+Z6/BdqeJ6qERRqw0GjGhiZOzheQKZD8KkxDga
kQCJwShXBGnuRUN20fofqzl0CbsaQT6WCXoUPnamAQKBgEY/ttlyLCrdHhamWlwN
ZkcgfsvQtLc//DGfEOSIiybs0eD0ORutxVQ2pwEgPI79xJTm0bdTHAFZVYziI9Lm
75k5WKxbBsYTgZm3i+LnnDtcHKPqkpXkq1v6WduTfaWpwMDJt0cJMOiTFzom76s1
mdFdmq2IXR+vXwl9f8fboc61
-----END RSA PRIVATE KEY-----'''

s = "AQEAN2+hgPwYzFATKPJfkXyTQKe9kvUTmT6LhASj2YI0T2KhBO7gSpKbNx/EXF4JYaWcwJVhJwiudgCFvoJMK9qJtnpLFmG12f8drygke+MPo5n2flHFPiKRmJCcCRM/VR8gL+xlbFIZNBL/o4onbqC1XfeQygiHe6tKXGiAZGXcJejbnob+/V+sL46x076KjurqLjcFMH+SCXomhuQZOiSqRqmeAsE6kL8wlj2yhTUfqAL/GuTTRziT6Syp0zJ7dprgCYOXBWbkLD9X6Vw39Db75kLd6Vx5zKT5jUQeU8eTN6pYfIiymlXwModf3TFBG1CObxzxzrevTXxFfIahFZGMAhDltmmcy7GUWDB7Qav24psONYaH+P69VfTimRzbrLMCfPb3zqp0cS8glMZ5YQuWqpigQRlQBhGq4rN9TGxBE3F1YRByBg+CHelBCHZj+2swHauVRmgy0CKU2/nmKpMrypKguFjjE6+bBur8b2AE28LSfjqxPZJx2BM="

code_bytes = s.encode('UTF-8')
by = base64.b64decode(code_bytes)
private_key = RSA.import_key(private_key_pem)
cipher = PKCS1_v1_5.new(private_key)
sentinel = get_random_bytes(16)
rsadecrypt = cipher.decrypt(by[3: 3 + 256], sentinel)
if rsadecrypt == sentinel:
    print('failure')
else:
    print(f'success: {rsadecrypt.hex(" ")}')

output is:

success: 48 90 c1 c5 ed fd 67 84 ad 82 df d1 5b 22 40 6f

I don't know what the rest of the bytes of s are all about.

PKCS1 version 1.5 encryption padding is not all that great and is basically deprecated in favor of OAEP padding. One of the weaknesses is the unacceptably high probability that a decryption with the wrong key and/or corrupted ciphertext will succeed. It's unlikely in this case, but not unlikely enough to completely discard the possibility. Although you've provided no additional details about what the payload is supposed to be, the 16 random-looking bytes suggests a key of some sort, perhaps an AES-128 key.

2 of 2
0

Try saving the private key you posted first in a file with the name 'pkey.pem', and instead of writing the string directly into your code, use the following to upload the key:

Pkey = RSA.importKey(open('pkey.pem').read())

For more information you can look here, the documentation of pycryptodome.


edited according to Topaco's comments

Your code should looks as follows:

from Crypto.PublicKey import RSA 
import base64
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Random import get_random_bytes

s="AQEAN2+hgPwYzFATKPJfkXyTQKe9kvUTmT6LhASj2YI0T2KhBO7gSpKbNx/EXF4JYaWcwJVhJwiudgCFvoJMK9qJtnpLFmG12f8drygke+MPo5n2flHFPiKRmJCcCRM/VR8gL+xlbFIZNBL/o4onbqC1XfeQygiHe6tKXGiAZGXcJejbnob+/V+sL46x076KjurqLjcFMH+SCXomhuQZOiSqRqmeAsE6kL8wlj2yhTUfqAL/GuTTRziT6Syp0zJ7dprgCYOXBWbkLD9X6Vw39Db75kLd6Vx5zKT5jUQeU8eTN6pYfIiymlXwModf3TFBG1CObxzxzrevTXxFfIahFZGMAhDltmmcy7GUWDB7Qav24psONYaH+P69VfTimRzbrLMCfPb3zqp0cS8glMZ5YQuWqpigQRlQBhGq4rN9TGxBE3F1YRByBg+CHelBCHZj+2swHauVRmgy0CKU2/nmKpMrypKguFjjE6+bBur8b2AE28LSfjqxPZJx2BM="
  
code_bytes = s.encode('UTF-8')
by=base64.b64decode(code_bytes)

Pkey = RSA.importKey(open('pkey.pem').read())

key = PKCS1_v1_5.new(Pkey)

sentinel = get_random_bytes(16)

rsadecrypt=key.decrypt(by,sentinel)

Pay attention that you still going to get the following error:

ValueError: Ciphertext with incorrect length.

as Topaco explained in the comments

🌐
Stuvel
stuvel.eu › python-rsa-doc › usage.html
5. Usage — Python-RSA 4.8 documentation
Alice encrypts the message using Bob’s public key, and sends the encrypted message. >>> import rsa >>> crypto = rsa.encrypt(message, bob_pub) Bob receives the message, and decrypts it with his private key.
🌐
OnboardBase
onboardbase.com › blog › rsa-encryption-decryption
RSA Encryption & Decryption In Python: Key Creation, Storage, Algorithm, and Forward Secrecy
April 24, 2022 - In this article, you are going to use PKCS1 OAEP, a modern RSA implementation. Let’s dive into each step in detail. First, we create a public encryption key and a private decryption key. Just like regular passwords, these keys need to be strong, meaning it won’t be realistically possible to brute force them with a software program in a reasonable amount of time. To achieve this, keys are randomly generated using methods provided by approved cryptography libraries, like pycryptodome in Python...
🌐
Medium
medium.com › coinmonks › rsa-encryption-and-decryption-with-pythons-pycryptodome-library-94f28a6a1816
RSA Encryption and Decryption with Python’s pycryptodome Library | by Miyoko Shimura | Coinmonks | Medium
November 9, 2024 - # Step 1: Install pycryptodome package !pip install pycryptodome # Import necessary modules from pycryptodome from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP # This module converts binary data to hexadecimal from binascii import hexlify # Step 2: Generate new RSA key # Create an RSA key pair with a key size of 1024 bits key = RSA.generate(1024) # Set the private_key variable to the generated key private_key = key # Derive the public key from the generated key public_key = key.publickey() # Step 3: Encrypt using public key # Create a PKCS1_OAEP cipher object with the publi
Find elsewhere
Top answer
1 of 3
25

Short answer

  • the code that you are using doesn't allow you to do that for security reasons
  • alternative code below

Long answer

I was curious about your problem and then I started to try to code

After a while I realized that if you run this snippet you will see that it correctly works:

#!/usr/bin/env python

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64

def generate_keys():
    modulus_length = 1024

    key = RSA.generate(modulus_length)
    #print (key.exportKey())

    pub_key = key.publickey()
    #print (pub_key.exportKey())

    return key, pub_key

def encrypt_private_key(a_message, private_key):
    encryptor = PKCS1_OAEP.new(private_key)
    encrypted_msg = encryptor.encrypt(a_message)
    print(encrypted_msg)
    encoded_encrypted_msg = base64.b64encode(encrypted_msg)
    print(encoded_encrypted_msg)
    return encoded_encrypted_msg

def decrypt_public_key(encoded_encrypted_msg, public_key):
    encryptor = PKCS1_OAEP.new(public_key)
    decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg)
    print(decoded_encrypted_msg)
    decoded_decrypted_msg = encryptor.decrypt(decoded_encrypted_msg)
    print(decoded_decrypted_msg)
    #return decoded_decrypted_msg

def main():
  private, public = generate_keys()
  print (private)
  message = b'Hello world'
  encoded = encrypt_private_key(message, public)
  decrypt_public_key(encoded, private)

if __name__== "__main__":
  main()

but if you now change two of the final lines [i.e. the role of the keys] into:

    encoded = encrypt_private_key(message, private)
    decrypt_public_key(encoded, public)

and rerun the program you will get the TypeError: No private key

Let me quote from this great answer:

"As it turns out, PyCrypto is only trying to prevent you from mistaking one for the other here, OpenSSL or Ruby OpenSSL allow you for example to do both: public_encrypt/public_decrypt and private_encrypt/private_decrypt

[...]

Additional things need to be taken care of to make the result usable in practice. And that's why there is a dedicated signature package in PyCrypto - this effectively does what you described, but also additionally takes care of the things I mentioned"

Adapting this link I came to the following code that should solve your question:

# RSA helper class for pycrypto
# Copyright (c) Dennis Lee
# Date 21 Mar 2017

# Description:
# Python helper class to perform RSA encryption, decryption, 
# signing, verifying signatures & keys generation

# Dependencies Packages:
# pycrypto 

# Documentation:
# https://www.dlitz.net/software/pycrypto/api/2.6/

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
import rsa

hash = "SHA-256"

def newkeys(keysize):
    random_generator = Random.new().read
    key = RSA.generate(keysize, random_generator)
    private, public = key, key.publickey()
    return public, private

def importKey(externKey):
    return RSA.importKey(externKey)

def getpublickey(priv_key):
    return priv_key.publickey()

def encrypt(message, pub_key):
    #RSA encryption protocol according to PKCS#1 OAEP
    cipher = PKCS1_OAEP.new(pub_key)
    return cipher.encrypt(message)

def decrypt(ciphertext, priv_key):
    #RSA encryption protocol according to PKCS#1 OAEP
    cipher = PKCS1_OAEP.new(priv_key)
    return cipher.decrypt(ciphertext)

def sign(message, priv_key, hashAlg="SHA-256"):
    global hash
    hash = hashAlg
    signer = PKCS1_v1_5.new(priv_key)
    if (hash == "SHA-512"):
        digest = SHA512.new()
    elif (hash == "SHA-384"):
        digest = SHA384.new()
    elif (hash == "SHA-256"):
        digest = SHA256.new()
    elif (hash == "SHA-1"):
        digest = SHA.new()
    else:
        digest = MD5.new()
    digest.update(message)
    return signer.sign(digest)

def verify(message, signature, pub_key):
    signer = PKCS1_v1_5.new(pub_key)
    if (hash == "SHA-512"):
        digest = SHA512.new()
    elif (hash == "SHA-384"):
        digest = SHA384.new()
    elif (hash == "SHA-256"):
        digest = SHA256.new()
    elif (hash == "SHA-1"):
        digest = SHA.new()
    else:
        digest = MD5.new()
    digest.update(message)
    return signer.verify(digest, signature)

def main():
    msg1 = b"Hello Tony, I am Jarvis!"
    msg2 = b"Hello Toni, I am Jarvis!"

    keysize = 2048

    (public, private) = rsa.newkeys(keysize)

    # https://docs.python.org/3/library/base64.html
    # encodes the bytes-like object s
    # returns bytes
    encrypted = b64encode(rsa.encrypt(msg1, private))
    # decodes the Base64 encoded bytes-like object or ASCII string s
    # returns the decoded bytes
    decrypted = rsa.decrypt(b64decode(encrypted), private)
    signature = b64encode(rsa.sign(msg1, private, "SHA-512"))

    verify = rsa.verify(msg1, b64decode(signature), public)

    #print(private.exportKey('PEM'))
    #print(public.exportKey('PEM'))
    print("Encrypted: " + encrypted.decode('ascii'))
    print("Decrypted: '%s'" % (decrypted))
    print("Signature: " + signature.decode('ascii'))
    print("Verify: %s" % verify)
    rsa.verify(msg2, b64decode(signature), public)

if __name__== "__main__":
    main()

Final notes:

  • the last prints have ascii because as stated here "In case of base64 however, all characters are valid ASCII characters"
  • in this case we are using the same key - the private one - both for encrypting and decrypting, so yes: we would end up to be symmetric but...
  • but - as stated here - "The public key is PUBLIC - it's something you would readily share and thus would be easily disseminated. There's no added value in that case compared to using a symmetric cipher and a shared key" plus "Conceptually, "encrypting" with the private key is more useful for signing a message whereas the "decryption" using the public key is used for verifying the message"
  • the same identical last principle is expressed in this answer - "Typically [...] we say sign with the private key and verify with the public key"
2 of 3
4

Looks like pycrypto has not been under active development since 2014 and support ended at python 3.3. cryptography seems like the standard now.

Using cryptography:

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend

password = b'thepassword'

key = rsa.generate_private_key(
    backend=default_backend(),
    public_exponent=65537,
    key_size=2048
)

private_key = key.private_bytes(
    serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8,
    serialization.BestAvailableEncryption(password)
)

public_key = key.public_key().public_bytes(
    serialization.Encoding.OpenSSH,
    serialization.PublicFormat.OpenSSH
)
🌐
Snyk
snyk.io › advisor › rsa › functions › rsa.privatekey
How to use the rsa.PrivateKey function in rsa | Snyk
For larger ' 'files, use the pyrsa-decrypt-bigfile command.') operation = 'decrypt' operation_past = 'decrypted' operation_progressive = 'decrypting' key_class = rsa.PrivateKey def perform_operation(self, indata, priv_key, cli_args=None): '''Decrypts files.''' return rsa.decrypt(indata, priv_key) class SignOperation(CryptoOperation): '''Signs a file.''' keyname = 'private' usage = 'usage: %%prog [options] private_key hash_method' description = ('Signs a file, outputs the signature.
🌐
Practical Cryptography
cryptobook.nakov.com › asymmetric-key-ciphers › rsa-encrypt-decrypt-examples
RSA Encrypt / Decrypt - Examples | Practical Cryptography for Developers
June 19, 2019 - Run the above code example: https://repl.it/@nakov/RSA-decryption-in-Python. A sample output of the code execution for the entire example is given below: ... If you run the above example, your output will be different, because it generates different random RSA key-pair at each execution. Even if you encrypt the same message several times with the same public key, you will get different output.
🌐
PyCryptodome
pycryptodome.readthedocs.io › en › latest › src › examples.html
Examples — PyCryptodome 3.23.0 documentation
from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP private_key = RSA.import_key(open("private.pem").read()) with open("encrypted_data.bin", "rb") as f: enc_session_key = f.read(private_key.size_in_bytes()) nonce = f.read(16) tag = f.read(16) ciphertext = f.read() # Decrypt the session key with the private RSA key cipher_rsa = PKCS1_OAEP.new(private_key) session_key = cipher_rsa.decrypt(enc_session_key) # Decrypt the data with the AES session key cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag) print(data.decode("utf-8"))
🌐
Stuvel
stuvel.eu › python-rsa-doc › reference.html
8. Reference — Python-RSA 4.8 documentation
DecryptionError – when the decryption fails. No details are given as to why the code thinks the decryption fails, as this would leak information about the private key. >>> import rsa >>> (pub_key, priv_key) = rsa.newkeys(256)
🌐
Nitratine
nitratine.net › blog › post › asymmetric-encryption-and-decryption-in-python
Asymmetric Encryption and Decryption in Python - Nitratine
September 16, 2018 - Anyone can encrypt data with your public key and then only those with the private key can decrypt the message. This also works the other way around but it is a convention to keep your private key secret.
🌐
YouTube
youtube.com › watch
RSA Private & Public Key Encryption in Python - YouTube
Today we learn how to do asymmetric encryption using RSA and private and public keys in Python.◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾📚 Programming Books & Merch 📚🐍 The Python ...
Published   August 25, 2022
🌐
Medium
medium.com › @mb20261 › python-by-examples-rsa-encryption-decryption-d07a226430b4
Python by Examples: RSA encryption & decryption | by MB20261 | Medium
January 19, 2024 - They should be always generated together in pair. Cipher Text — Refers to encrypted text. Encryption and Decryption — You could use public key to encrypt message, and use private key to decrypt message.
🌐
GitHub
github.com › nakov › Practical-Cryptography-for-Developers-Book › blob › master › asymmetric-key-ciphers › rsa-encrypt-decrypt-examples.md
Practical-Cryptography-for-Developers-Book/asymmetric-key-ciphers/rsa-encrypt-decrypt-examples.md at master · nakov/Practical-Cryptography-for-Developers-Book
Next, encrypt the message using RSA-OAEP encryption scheme (RSA with PKCS#1 OAEP padding) with the RSA public key: msg = b'A message for encryption' encryptor = PKCS1_OAEP.new(pubKey) encrypted = encryptor.encrypt(msg) print("Encrypted:", binascii.hexlify(encrypted)) Run the above code example: https://repl.it/@nakov/RSA-encryption-in-Python. decryptor = PKCS1_OAEP.new(keyPair) decrypted = decryptor.decrypt(encrypted) print('Decrypted:', decrypted)
Author   nakov
🌐
Reddit
reddit.com › r/learnpython › cannot decrypt file using rsa private key and cryptography package
r/learnpython on Reddit: Cannot decrypt file using RSA private key and Cryptography Package
December 24, 2023 -

Does anyone have experience of using the Cryptography package with an RSA Key (in PEM format) to decrypt files and could shed some light on what's wrong here please?

The decryption works with the following OpenSSL command:

openssl rsautl -decrypt -keyform PEM -inkey RSAPrivateKey.pem.key -in <file_to_decrypt>.ky2

But using the Cryptography package, I just get "Encryption/decryption failed". I added a try/except clause, but it didn't provide much further info:

from cryptography.hazmat.primitives import serializationfrom cryptography.hazmat.primitives.asymmetric import rsafrom cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives import hashesimport binascii

[…]
with open(‘RSAPrivateKey.pem.key’, 'rb') as oKey:
    key = oKey.read()
with open(ky2_path, 'r') as oKy2:
    ky2 = oKy2.read() # <-- ky2 holds the cyphertext to be decrypted
[…]

# Load RSA Private Key from PEM:
private_key = serialization.load_pem_private_key( key, password=None, backend=default_backend() )

# Decrypt the ciphertext:
decrypted_data = private_key.decrypt( ky2,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(),label=None) )

It seems possible that the padding is wrong, but I don't have information from the third party who encrypted the files about how the padding is set.

🌐
GeeksforGeeks
geeksforgeeks.org › how-to-encrypt-and-decrypt-strings-in-python
How to Encrypt and Decrypt Strings in Python? - GeeksforGeeks
August 14, 2024 - Generate public and private keys with rsa.newkeys() method. Encode the string to byte string. Then encrypt the byte string with the public key. Then the encrypted string can be decrypted with the private key.
🌐
University of Toronto
teach.cs.toronto.edu › ~csc110y › fall › notes › 08-cryptography › 05-rsa-cryptosystem-implementation.html
8.5 Implementing RSA in Python
def rsa_decrypt(private_key: tuple[int, int, int] ciphertext: int) -> int: """Decrypt the given ciphertext using the recipient's private key.