Introduction
Cryptography and computer network security have always been side interests for me. While reading about the RSA encryption technique in cryptography, I thought about writing an article on this amazing algorithm. Python is one of my favorite programming languages because of its simplicity, and implementing RSA Encryption using python will be fun. Let’s dive into the concepts of RSA encryption.
What is Encryption?
Encryption means encoding information. In technical terms, encryption is converting human-readable plaintext to alternative text, also known as ciphertext. Only authorized parties can decipher a ciphertext back to plaintext and access the original information.
What is RSA Encryption in python?
RSA abbreviation is Rivest–Shamir–Adleman. This algorithm is used by many companies to encrypt and decrypt messages. It is an asymmetric cryptographic algorithm which means that there are two different keys i.e., the public key and the private key. This is also known as public-key cryptography because one of the keys can be given to anyone. Companies such as Acer, Asus, HP, Lenovo, etc., use encryption techniques in their products.
Since this is asymmetric, nobody else except the browser can decrypt the data even if a third-party user has a public key in the browser.
RSA Encryption Implementation Without Using Library in Python
How does RSA algorith work?
Let us learn the mechanism behind RSA algorithm :
- How to generate Public Key for encryption:
- Take two prime numbers such as 17 and 11.
- multiply the prime numbers and assign them to a variable. n= 7*11=77
- Assume a small exponent e which will lie between 1 to phi(n). Let us assume e=3
Now, we are ready with our public key(n = 77 and e = 3) .
Encryption:
memod(n) = 893mod 77 = 166 = c
import math
message = int(input("Enter the message to be encrypted: "))
p = 11
q = 7
e = 3
n = p*q
def encrypt(me):
en = math.pow(me,e)
c = en % n
print("Encrypted Message is: ", c)
return c
print("Original Message is: ", message)
c = encrypt(message)
OUTPUT:-
Enter the message to be encrypted: 89 Original Message is: 89 Encrypted Message is: 166
As you can see from the above, we have implemented the encryption of a message without using any library function. But as we are using python, we should take some advantage out of it. By this, I mean to say that we are having libraries available for the RSA implementation. Oh! Yeah, you heard it right.
RSA Encryption Implementation Using Library in Python
There are many libraries available in python for the encryption and decryption of a message, but today we will discuss an amazing library called pycryptodome.
The RSA algorithm provides:
- Key-pair generation: generate a random private key and public key (the size is 1024-4096 bits).
- Encryption: It encrypts a secret message (integer in the range [0…key_length]) using the public key and decrypts it back using the secret key.
- Digital signatures: sign messages (using the private key) and verify message signature (using the public key).
- Key exchange: It securely transports a secret key used for encrypted communication.
Before starting to code in python do not forget to install the library.
pip install pycryptodome
Now let’s understand how the RSA algorithms work by a simple example in Python. The below code will generate a random RSA key-pair, will encrypt a short message using the RSA-OAEP padding scheme.
RSA key generation
Now, let’s write the Python code. First, generate the RSA keys (1024-bit) and print them on the console as hex numbers and the PKCS#8 PEM ASN.1 format.
pip install pycryptodome
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii
keyPair = RSA.generate(3072)
pubKey = keyPair.publickey()
print(f"Public key: (n={hex(pubKey.n)}, e={hex(pubKey.e)})")
pubKeyPEM = pubKey.exportKey()
print(pubKeyPEM.decode('ascii'))
print(f"Private key: (n={hex(pubKey.n)}, d={hex(keyPair.d)})")
privKeyPEM = keyPair.exportKey()
print(privKeyPEM.decode('ascii'))
#encryption
msg = 'A message for encryption'
encryptor = PKCS1_OAEP.new(pubKey)
encrypted = encryptor.encrypt(msg)
print("Encrypted:", binascii.hexlify(encrypted))
OUTPUT:-
Public key: (n=0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20e36ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, e=0x10001)
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaEUhbzLlWlBCoSPsa/fKoGxfB
+p+etUb9HeuHO0m2k
-----END PUBLIC KEY-----
Private key: (n=0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20eb8362c085cd5b28ba109dbad2bd257a013f57f745402e245b0cc2d553c7b2b8dbba57ebda7f84cfb32b7d9c254f03dbd0188e4b8e40c47b64c1bd2572834b936ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, d=0x318ab12be3cf0d4a1b7921cead454fcc42ba070462639483394d6fb9529547827e9c8d23517b5566dd3d3e5b16ec737987337a0e497fdba4b5ad97af41c1c3cdd87542a4637d81)
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCaEUhbzLlWlBCoSPsa/fKoGxfB+p+etUb9HeuHO0m2k6Tt8g64
NiwIXNWyi6EJ260r0legE/V/dFQC4kWwzC1VPHsrjbulfr2n+Ez7MrfZwlTwPb0B
iOS45AxHtkwb0lcoNLk2/8PamVNlfvi+6AxJwsEpM8ijSASgDrTIEkjgHwIDAQAB
AoGAMYqxK+PPDUobeSHOrUVPzEK6BwRiY5SDOU1vuVKVR4J+nI0jspSo4B+KEBna
NONQ8jB3QOBqJwvvH+ZG5q0hPjG1KP3V9dA+YzwHxEdV7WIqYp156CLAlevfnMgO
UXtVZt09PlsW7HN5hzN6Dkl/26S1rZevQcHDzdh1QqRjfYECQQDGDUIQXlOiAcGo
d5YqAGpWe0wzJ0UypeqZcqS9MVe9OkjjopCkkYntifdN/1oG7S/1KUMtLoGHqntb
c428zOO/AkEAxyV0cmuJbFdfM0x2XhZ+ge/7putIx76RHDOjBpM6VQXpLEFj54kB
qGLAB7SXr7P4AFrEjfckJOp2YMI5BreboQJAb3EUZHt/WeDdJLutzpKPQ3x7oykM
wfQkbxXYZvD16u96BkT6WO/gCb6hXs05zj32x1/hgfHyRvGCGjKKZdtwpwJBAJ74
y0g7h+wwoxJ0S1k4Y6yeQikxUVwCSBxXLCCnjr0ohsaJPJMrz2L30YtVInFkHOlL
i/Q4AWZmtDDxWkx+bYECQG8e6bGoszuX5xjvhEBslIws9+nMzMuYBR8HvhLo58B5
N8dk3nIsLs3UncKLiiWubMAciU5jUxZoqWpRXXwECKE=
-----END RSA PRIVATE KEY-----
Encrypted: b'99b331c4e1c8f3fa227aacd57c85f38b7b7461574701b427758ee4f94b1e07d791ab70b55d672ff55dbe133ac0bea16fc23ea84636365f605a9b645e0861ee11d68a7550be8eb35e85a4bde6d73b0b956d000866425511c7920cdc8a3786a4f1cb1986a875373975e158d74e11ad751594de593a35de765fe329c0d3dfbbfedc'
Explanation of the code
- Installed pycryptodome.
- As we are using the RSA algorithm, we need to import it from Crypto.PublicKey.
- We are also using the OAEP-Padding scheme. We have imported PKCS1_OAEP from Crypto.cipher.
- To convert binary to ASCII, we have imported binascii.
- Generating keypair values using RSA.generate.
- Generating publickey value
- Entering a message that is needed to be encrypted.
- Using encrypt function to encrypt the message.
As you can see after installing a library our work became very simpler and more efficient.
Also Read | Python SHA256: Implementation and Explanation
Conclusion
In today’s detailed discussion, we have covered almost everything about RSA encryption implementation using python. Starting from the basics to encryption, we have understood about RSA algorithm. We have implemented RSA using a library and without using a library. But I recommend using the library pycryptodome as it is more efficient.
Nowadays, almost every MNC uses encryption for their information as hacking is quite easy in today’s world. However, encryption of the information makes it a difficult task for hackers to understand the data.
If you have any doubts, feel free to comment down below. Till then, keep exploring our tutorials.
Hi, there!! Thank you… Looks nice. How to use it on files in a directory? How to encrypt and decrypt the files? How to encrypt a file and send it to someone else to decrypt it? May you send me some examples, please. Regards, IOS
Yes, you can easily do that with python. First of all, ask the receiver to generate RSA keys using
publicKey, privateKey = rsa.newkeys(512)
. Then ask him for the public key and encrypt the file data usingencMessage = rsa.encrypt(message.encode(), publicKey)
. Nextly, send him the encoded message where he’ll use his private key to decrypt the message.decMessage = rsa.decrypt(encMessage, privateKey).decode()
can be used for the same. Please, note that after the creation of the private key, it shouldn’t be shared between sender and receiver to compromise the security.In the case of files, you can read the file contents using file.read() method and then encrypt the whole content.
Hi, thank you for sharing this, just what i was looking for.
I installed the lib and when running this code, i get an error at this line:
encrypted = encryptor.encrypt(msg)
The error reads:
File “…..\PKCS1_OAEP.py”, line 121, in encrypt
db = lHash + ps + b’\x01′ + _copy_bytes(None, None, message)
TypeError: can’t concat str to bytes
Would you be able to help with this?
Best regards!
This error is raised when there is a problem in converting strings to bytes. When you use a file as input, you can get this error more often due to different characters. You can use bytes of data to encrypt your message. The following example will help you –
data = b'Text to encrypt'
encryptor = PKCS1_OAEP.new(pubKey) encrypted = encryptor.encrypt(data) print("Encrypted:", binascii.hexlify(encrypted))
If you are taking input from a file, make sure you use ‘rb’ as file mode.
I hope this clarifies everything. Let me know if you have any other doubt!
Regards,
Pratik
I fix it by adding .encode() after msg in the encrypt() method. When I use an online RSA decryptor to try and decrypt the encrypted message with the private key is it never able to. How can I check the correctness of the encryption?
Yes, .encode() also works as it converts strings to bytes. RSA has different Cipher methods (RSA/ECB/PKCS1Padding is the most used one) which may prevent proper encryption and decryption when you change systems. To check the correctness, you may have to first check the key size, and matching public and private keys. Generally, remember that a public key is used to encrypt and a private key is used to decrypt.
Hope this helps. If not, please let me know!
Regards,
Pratik
encrypted = encryptor.encrypt(msg.encode())
ITS NOT WORKING, there is no module named Crypto with an upper case C
ModuleNotFoundError: No module named ‘Crypto’
pip install pycryptodome
will solve the issue.if we install pycryptodome as you suggested,
will it understand
this Crypto with uppercase C?
Yes it does. “Crypto” is included in pycryptodome.
we are using pycharm from jetbrains, it gives errors when we try to install pycryptodome… what we do? where can we run it so that pycryptodome will be installed and be available so the rest can execute as well?
I suggest you use normal Python installation from python.org then. Make sure you select the “Add to Path” option while selecting and after installing just run “pip install pycrytodome” and run the program by using “python“.
it worked as you suggested, THANK YOU!
How do you decrypt the data without using a library? and are the original numbers 7 and 11 the private key?
Using a library would be the best and safest way to do it. In cryptography don’t try to reinvent the wheel. I’ll give you errors and risks 🙂
Regards,
Pratik
How we can apply this on an image ?
I’d suggest you read the image as a byte and then try to encrypt the byte array. You might need to change the values of a few byte characters as they need to be less than the value of Modulo.
Regards,
Pratik
How can we decrypt encrypted message?
You can use keyPair.decrypt(encrypted) to decrypt the message.
Regards,
Pratik
NotImplementedError: Use module Crypto.Cipher.PKCS1_OAEP instead
Try using:
decryptor = PKCS1_OAEP.new(key)
decrypted = decryptor.decrypt(ast.literal_eval(str(encrypted)))
modBits = Crypto.Util.number.size(self._key.n)
AttributeError: ‘bytes’ object has no attribute ‘n’
Which public-key are you using? It should be the recipient’s public key.
Hi.. how we can find memory usage of this program in python.
how can we use profiler as no definition is there.. any other suggestions
You can use memory_profiler to check the memory consumption of this program. More info can be found on Github.
How to encrypt the random key using cryptography instead of pycryptodome
You can always generate a key in cryptography using
Fernet.generate_key()
. And then use the key to encrypt the message.