How to use RSA public key to decrypt ciphertext in Python?

RSA public key decryption is an unreasonable design. But now I do need it :joy:

Can you give more details about what you’re doing? Are you using a particular cryptography library (if so, which one?), or is this a toy implementation for educational / learning purposes? What form does the ciphertext take? If it’s a string, how has it been converted from the integer or integer stream that RSA operates on (and how was the original plaintext converted to such an integer)?

Can you show us the code that you’re using to do the encryption? That would answer a lot of questions.

Why is it unreasonable? It’s just a process, a fixed set of steps you follow, depending on the specific library you used to run it. The details depend on what type of ciphertext you have, as well as how secure your process must be against attacks. A toy project has very different requirements from software that is entrusted to handle monetary transfers, for example.

A good library will include examples of how to use it. For example, the cryptography package includes a RSA decryption example, which uses an existing private_key variable to decrypt ciphertext, given (in addition to the ciphertext) a padding configuration. The latter is necessary because there are multiple ways you can pad out encrypted data to fixed-length blocks.

thanks @mjpieters @mdickinson
I use this library. https://pypi.org/project/rsa/
I am not very good at English. I try to use code to describe my purpose

import rsa
import base64

# Private key decryption
def fun1():
    publicKey, privateKey = rsa.newkeys(512)
    cipher = rsa.encrypt(b'Hello World!', publicKey)
    base64Text = base64.b64encode(cipher).decode()

    print(base64Text)

    text = rsa.decrypt(base64.b64decode(base64Text.encode()), privateKey)
    print(text.decode())

# Public key decryption
def fun2():
    publicKey, privateKey = rsa.newkeys(512)
    cipher = rsa.encrypt(b'Hello World!', privateKey)
    base64Text = base64.b64encode(cipher).decode()

    print(base64Text)

    text = rsa.decrypt(base64.b64decode(base64Text.encode()), publicKey) # AttributeError: 'PublicKey' object has no attribute 'blinded_decrypt'
    print(text.decode())


fun1() # success
fun2() # fail

Is there something wrong with my operation? I learned about this problem in search engine. Many people say that RSA private key encryption has some security problems. So this library does not have this API .

Don’t try to use a public RSA key to decrypt, and by extension, don’t try to use a private RSA key to encrypt:

Is RSA encryption with a private key the same as signature generation?

RSA encryption can only be performed with an RSA public key according to the RSA standard.

bold emphasis mine.

The library you are using already has a (closed) ticket on the same attribute error: https://github.com/sybrenstuvel/python-rsa/issues/92. While technically speaking generating a signature with the public key constitutes encryption, there are enough differences in how public and private keys are used that it is not surprising that this library doesn’t support explicitly using the private key to encrypt with.

You see this in other implementations too. The cryptography library delegates encryption, decryption, signing and verification to the key instance, but only the RSA public key class can encrypt and verify, and the only private key can decrypt and sign.

And the PyCryptodome library includes a handy table to explain how to use public and private keys:

Algorithm Sender uses… Receiver uses…
Encryption Public key Private key
Signature Private key Public key

It is hugely important to keep your private key secret. The public key, on the other hand, is assumed to be public, and so doesn’t need special care. The special care RSA cryptography implementations should take to protect your private key is expensive in terms of software development time and verification that your private key is kept secure from prying eyes, so this care is often not applied to code paths that are meant to only be used with a public key. This means that using your private key where a public key is expected can lead to your private key being leaked to attackers.

1 Like

Thank you very much for your serious answer!

Was this intended to be “Don’t try to use a public RSA key to decrypt”?

1 Like

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!

2 Likes