It is as you say indeed possible to encrypt with private and decrypt with public, the mathematical symmetry in RSA allows just swapping e/d in the keys and then calling the encrypt/decrypt functions.
This being said, I want to emphasize that I'm not a crypto expert and cannot say for certain that this doesn't compromise security.
So, you could extend the RSA-Key class with that swapped logic, use blackmagic to swap the implementation of the loaded key, and pass it to the normal functions:
from Crypto.PublicKey.RSA import RsaKey
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Math.Numbers import Integer
class SwappedRsaKey(RsaKey):
def _encrypt(self, plaintext):
# normally encrypt is p^e%n
return int(pow(Integer(plaintext), self._d, self._n))
def _decrypt(self, ciphertext):
# normally decrypt is c^d%n
return int(pow(Integer(ciphertext), self._e, self._n))
data = "I met aliens in UFO. Here is the map.".encode("utf-8")
# It's important to also use our swapped logic in encryption step, otherwise the lib would still use e&n (the private contains all 3 values).
private_key = RSA.import_key(open("mykey.pem").read())
private_key.__class__ = SwappedRsaKey
public_key = RSA.import_key(open("mykey.pub").read())
public_key.__class__ = SwappedRsaKey
cipher_priv = PKCS1_OAEP.new(private_key)
cipher_pub = PKCS1_OAEP.new(public_key)
enc_data = cipher_priv.encrypt(data)
# Decrypt again, just a showcase to prove we can get the value back
dec_data = cipher_pub.decrypt(enc_data)
print(dec_data.decode("utf-8"))
Answer from Tobias K. on Stack Overflow
» pip install rsa
cryptography - Python library for RSA public decryption - Stack Overflow
RSA encryption and decryption in Python - Stack Overflow
How to use RSA public key to decrypt ciphertext in Python?
What cryptography module is everyone using for Python (2024 edition)?
Videos
It is as you say indeed possible to encrypt with private and decrypt with public, the mathematical symmetry in RSA allows just swapping e/d in the keys and then calling the encrypt/decrypt functions.
This being said, I want to emphasize that I'm not a crypto expert and cannot say for certain that this doesn't compromise security.
So, you could extend the RSA-Key class with that swapped logic, use blackmagic to swap the implementation of the loaded key, and pass it to the normal functions:
from Crypto.PublicKey.RSA import RsaKey
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Math.Numbers import Integer
class SwappedRsaKey(RsaKey):
def _encrypt(self, plaintext):
# normally encrypt is p^e%n
return int(pow(Integer(plaintext), self._d, self._n))
def _decrypt(self, ciphertext):
# normally decrypt is c^d%n
return int(pow(Integer(ciphertext), self._e, self._n))
data = "I met aliens in UFO. Here is the map.".encode("utf-8")
# It's important to also use our swapped logic in encryption step, otherwise the lib would still use e&n (the private contains all 3 values).
private_key = RSA.import_key(open("mykey.pem").read())
private_key.__class__ = SwappedRsaKey
public_key = RSA.import_key(open("mykey.pub").read())
public_key.__class__ = SwappedRsaKey
cipher_priv = PKCS1_OAEP.new(private_key)
cipher_pub = PKCS1_OAEP.new(public_key)
enc_data = cipher_priv.encrypt(data)
# Decrypt again, just a showcase to prove we can get the value back
dec_data = cipher_pub.decrypt(enc_data)
print(dec_data.decode("utf-8"))
First of all, big thanks to Tobias K. for the short and clear answer. It worked flawlessly.
But when I tried to decrypt the server messages, pycryptodome kept returning sentinel instead of decrypted data. I decided to look into the library source code, and check what would .decrypt() return if I comment out this lines in .../Crypto/Cipher/PKCS1_v_1_5.py:
if not em.startswith(b'\x00\x02') or sep < 10:
return sentinel
And to my surprise it returned the decrypted message! Not sure that I didn't break something, but it works. I guess it was a bug? This is aleready fixed in their github repo, but the version is not released yet
» pip install rsa-python
In order to make it work you need to convert key from str to tuple before decryption(ast.literal_eval function). Here is fixed code:
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import ast
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate pub and priv key
publickey = key.publickey() # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print('encrypted message:', encrypted) #ciphertext
f = open ('encryption.txt', 'w')
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(ast.literal_eval(str(encrypted)))
print('decrypted', decrypted)
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
PKCS#1 OAEP is an asymmetric cipher based on RSA and the OAEP padding
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Cipher import PKCS1_OAEP
def rsa_encrypt_decrypt():
key = RSA.generate(2048)
private_key = key.export_key('PEM')
public_key = key.publickey().exportKey('PEM')
message = input('plain text for RSA encryption and decryption:')
message = str.encode(message)
rsa_public_key = RSA.importKey(public_key)
rsa_public_key = PKCS1_OAEP.new(rsa_public_key)
encrypted_text = rsa_public_key.encrypt(message)
#encrypted_text = b64encode(encrypted_text)
print('your encrypted_text is : {}'.format(encrypted_text))
rsa_private_key = RSA.importKey(private_key)
rsa_private_key = PKCS1_OAEP.new(rsa_private_key)
decrypted_text = rsa_private_key.decrypt(encrypted_text)
print('your decrypted_text is : {}'.format(decrypted_text))
I need to generate an RSA keypair in python. Sadly there's no standard lib for cryptography in Python, so I was wondering what everyone is using for cryptography?
There's pycryptodome, python-gnupg, pyopenssl, and cryptography.io. Which is the most popular, well maintained (preferably has a long history of proven development), and accuracy in generating secure keys?
I'm leaning towards cryptography.io but I'm not familiar with the crypto space. What's the best?