RSA is among the hottest strategies for public key cryptography. You would possibly assume that RSA (Public-Non-public Key Encryption) is straightforward since you simply encrypt with the recipient’s public key, and decryption is completed with the recipient’s non-public key. Nevertheless, there’s an issue. RSA can solely encrypt as much as 245 bytes of knowledge at a time.
As a rule of thumb, you’ll be able to solely encrypt knowledge of the identical size because the RSA key size. Due to this fact, in case you have a 4096-bit RSA key, you’ll be able to solely encrypt messages as much as 4096 bits lengthy. Not solely that, but it surely’s extremely gradual. With a 2048-bit RSA key, you’ll be able to encrypt 2048/8 = 256 bytes at a time. Why is RSA restricted to encrypting solely 245 bytes of knowledge? It’s because the padding requirements PKCS1 (requires 11 bytes) and OAEP require extra padding (42 or 66 bytes). RSA encryption makes use of two varieties of padding. PKCS#1v1.5 (commonplace) makes use of 11 bytes, OAEP padding (newest/beneficial) makes use of 42 or 66 bytes. This system written right here makes use of OAEP padding.
However why use padding in RSA within the first place?
Uncooked RSA encryption with out padding will not be safe. Padding prevents an attacker from guessing small or predictable messages and causes them to supply totally different ciphertext every time the identical message is encrypted.
RSA points
Both means, RSA has its issues. When you’ve got a big doc, you’ll be able to’t hold encrypting it slowly at 245 bytes at a time. The principle downside with RSA is that it’s computationally very costly and time consuming. So as a substitute of encrypting the whole doc or communication with RSA, do the next:
- Encrypt with symmetric encryption AES
- Keys utilized in symmetric encryption are encrypted utilizing RSA.
- On this means, essentially the most delicate data (symmetric keys) is extremely protected by public key cryptography.
AES is a symmetric block cipher and could be very quick. Plaintext is split into chunks known as blocks, and every block is encrypted on a sequence. There are alternative ways (additionally known as modes of operation) to do that: ECB (digital code guide), CBC (cipher block chain), and CFB (cipher suggestions).
Nevertheless, AES is a symmetric encryption algorithm, so it requires symmetric keys that have to be exchanged. So as a substitute of encrypting the whole unique message with RSA (which could be very inefficient and cumbersome), you’ll be able to encrypt an AES symmetric key with RSA, and when the recipient opens the symmetric key along with his or her RSA non-public key, the recipient can retrieve the AES symmetric key to decrypt the unique AES-encrypted message.
So the steps are:
1. Get the plaintext that must be encrypted. This plain textual content is encrypted utilizing AES symmetric encryption. The important thing used is a 256-bit (32-byte) key.
2. Notice that the AES symmetric key itself is encrypted utilizing an RSA 2048-bit key (as much as 245 bytes may be encrypted, which is far bigger than the 32-byte key it encrypts).
So, if you happen to convert the above steps right into a program…
Program 1: Assume you’ve an AES symmetric key (256 bits or 32 bytes). This program performs AES encryption and decryption utilizing a 256-bit symmetric key. Within the pattern program, the bottom line is “AAAAAAAAAAAAAAAA” and this secret’s encrypted in program 2.
Program 2: Now that we now have the AES symmetric key for use. This program performs RSA encryption and decryption of the important thing itself. The general public/non-public key pair used right here is generated from Program 3.
Program 3: Nevertheless, working RSA requires the era of a public-private key. This program generates private and non-private keys. In commonplace trade purposes, P and Q utilized in RSA are prime numbers 300 digits lengthy. Program 4 has been added for instructional causes.
Program 4: The precise public/non-public key pair era is completed from P, Q, N, E, and D. The prime numbers chosen are P and Q. These are 300 digit prime numbers. E is Fermat prime and is assured to be coprime to (P-1)*(Q-1) for any chosen P,Q, so it’s at all times chosen as 65537. Due to this fact, this program is a pleasant program that demonstrates the identical process with P and Q chosen as small prime numbers, in contrast to the 300-digit prime numbers chosen programmatically in Program 3. The general public-private pair right here can’t be used with the RSA-AES mixture above. That is for understanding functions solely.
Program 1: AESEncryption.py
import base64
Import AES from Crypto.Cipher
Import padding and unpadding from Crypto.Util.Padding
AES ECB mode with out #IV
knowledge = ”'{textual content: “That is plain textual content that’s encrypted and decrypted utilizing an AES symmetric key. – Uniminds”}”’
key = ‘AAAAAAAAAAAAAAA’ #have to be 16 characters for AES128
Default encryption (uncooked):
uncooked = pad(uncooked.encode(),16)
cipher = AES.new(key.encode(‘utf-8’), AES.MODE_ECB)
returnbase64.b64encode(cipher.encrypt(uncooked))
def decryption (enc):
enc =base64.b64decode(enc)
cipher = AES.new(key.encode(‘utf-8’), AES.MODE_ECB)
return unpad(cipher.decrypt(enc),16)
Encryption = encryption(knowledge)
print(‘Encrypted ECB Base64:’,encrypted.decode(“utf-8”, “ignore”))
encrypted=encrypted.decode(“utf-8”, “ignored”)
decryption = decryption (encryption)
print(‘Decrypted knowledge: ‘,decrypted.decode(“utf-8”, “ignore”))
Program 2: RSAEncryptionOfAESKey.py
Crypto.Cipher import from PKCS1_OAEP
Import RSA from Crypto.PublicKey
Import b64encode from Base64
Import b64decode from Base64
# work
Message = b’AAAAAAAAAAAAAAA’
key = RSA.importKey(”’—–BEGIN public key—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4GgqnTicIUF9pGEEQ44e
FY1rc+7Dh4/sCPqfzauYf73gyxaFs1eAhZnVh39b/G05yCq2ztozwHBx4S3A62DT
hDGZM5ZRZCxgtKhuyR976pLwWx9Nk0vKJ3K6qz5QWFFjBmb2Q4dpHA3Yy7jiwOPj
hUqfpZEqrwoBmSdsUUMrBcPAwt9A0XH5hJcK8thkJ2q8f8wRdaSLpeWgY7JTRDxM
GFRJ6uHLTLbunRKWnvl4FWhdGFejHCdrcX27cWp5OiYHapJQ9V25kSn6X6W06g4C
RCeE0ncSnaEkaKVTjICFcEq1rWiHX29dnsJVX30he9V+gjIXgpFKOfcyD6Y2bPFp
Pidakabu
—–Finish of public key—–”’)
Cipher = PKCS1_OAEP.new(key)
Ciphertext = cipher.encrypt(message)
print(“ciphertext”, b64encode(ciphertext).decode(‘utf-8’))
encodedText=b64encode(ciphertext).decode(‘utf-8’)
ct = b64decode(encoded textual content)
Ciphertext=ct
key = RSA.importKey(”’—–BEGIN PRIVATE KEY—–
MIIEowIBAAKCAQEA4GgqnTicIUF9pGEEQ44eFY1rc+7Dh4/sCPqfzauYf73gyxaF
s1eAhZnVh39b/G05yCq2ztozwHBx4S3A62DThDGZM5ZRZCxgtKhuyR976pLwWx9N
k0vKJ3K6qz5QWFFjBmb2Q4dpHA3Yy7jiwOPjhUqfpZEqrwoBmSdsUUMrBcPAwt9A
0XH5hJcK8thkJ2q8f8wRdaSLpeWgY7JTRDxMGFRJ6uHLTLbunRKWnvl4FWhdGFej
HCdrcX27cWp5OiYHapJQ9V25kSn6X6W06g4CRCeE0ncSnaEkaKVTjICFcEq1rWiH
X29dnsJVX30he9V+gjIXgpFKOfcyD6Y2bPFpPQIDAQABAoIBAB7TKDFeGf+WcaYD
/pQyAB9pRN6QqFKleiB0nsFfZgv7/tYewqBTL3AKpMpfO/k1XrfIaEKLNgsj1vy9
rm+Wpg9VScxMhGMcdm8yaL9fQAQFiZcWum72fO8Ewy/1GA+9pDrTp1W40r8cBtDb
FWi2FQFw8fOJ+IFBQF1zjR0vewgoLNzDpjfBby8vQUvQ2Wgh0Y+hNOTackTackminN
CKwdx+zLNYYz4howlmDU9mVg+gOyjuoDpmghJTqPd5+C9g6HVA2W20DSij1U7uW4
4e6BwAjViqYX36d3YXB6FE5pRAhzaCbXLGjAYnBCZrMR/Zvmi3Cj5PrrPVq/agp4
6/i9Q7ECgYEA5xAr1KHDZDXkB2PjCA73vIw4HTB4rIkN2pgZ4kvW49/Ytc21k8Ex
RFZBj42pLJHCnMtNwuJhULLJphz19Ld/sr2o56YqNIoohuVgLu4uviqnZ2r1feDo
2yJ7UKNh+nWgfJZnKEgUPgTiLMXjuhDvvGYF69RDyyHUKDh2P8bbMZECgYEA+KAY
bogxe2P43RhMrWiLLuOGShNwamZvXgkXxS0T3nYAypTBHQD4VGQciygNjGkQSAe/
yrDPoL4vnfNYqx1ETD8BCHYAtRyHHxI5wpnoTtNAPr5GY4YZDdZFD7qhG33Vd1ba
JjYqo7WxH9lmbMnICEUUDSPK3J4wn48rvfuZJu0CgYB7PKrD68sUxZFrR6EtCR6k
l3zORK34B9k1v23+vkhMnXUt8htoROAL/J1W/U0/kjZj/iLpUGhq7BCU4llkPgKD
yJgvhPZ5sz5ORER6g1q23nUOuYNZsf0/8zImHh4BwX7pNCas21TAh0ZCbwE4mhPj
Pd7mmv3Vd6N6GDMpbNw3oQKBgQCsE6o0HlS5EQ1agQn47yV9023LcT7Z9YHY9LQl
/TgGPWf4zhIGb/hv+EYLhiKeOES6YId2Fgr6dXtHVLeQ8hueTrOz1VYBKGkqKmf
fYRioiWSB4GSOmq2v/lWlJYS//mxukQMNGs4mXU5FO+mFdZEuu94z8gE/9upY58j
w7JRVQKBgFWGRZVDZCHfc/mNEKmdFxh3YOxjuG65AIkPL7bSt4ek2Ul9U8ZYj5/x
wf7EvKzk5L6Ahw7UHcXlIY0Ih26s7gzUMgFxssqx4JqtHTh3TPon/EUdjbQ4tUv5
uMBwwTB/OXsvhnv9lO1CbgnBddGPnPqu8ix6uBG5ccSpNSddzKgB
—–Final non-public key—–”’)
Cipher = PKCS1_OAEP.new(key)
Message = cipher.decrypt(ciphertext)
print(“Decrypted textual content”,message)
Program 3: keygen1.py
Import RSA from Crypto.PublicKey
def createPublicPrivateKey():
# Generate an RSA key pair (2048 bits)
Key = RSA.generate(2048)
# Export the non-public key within the format most popular by program 2
private_key = key.export_key().decode(‘utf-8’)
# Export public key
public_key = key.publickey().export_key().decode(‘utf-8’)
return {
“Public key”: public_key,
“Non-public key”: private_key
}
if __name__ == “__main__”:
Key = createPublicPrivateKey()
print(“— copy this to program 2’s public key —”)
print(key[“publicKey”])
print(“n— Copy this to program 2’s non-public key —”)
print(key[“privateKey”])
Program 4: KeyGenWithPQ.py
from cryptography.hazmat.primitives.ametric import rsa
Import serialization from cryptography.hazmat.primitives
def create_rsa_from_primes(p, q, e=65537):
# Calculate RSA parts
n = p * q
Phi = (p – 1) * (q – 1)
If e >= n:
elevate ValueError(f”Public exponent {e} is bigger than modulus {n}. Please use a bigger prime quantity!”)
# Compute the non-public index d.
d = pow(e, -1, phi)
# Calculate the CRT coefficient (required by the library to construct the important thing)
dmp1 = d% (p – 1)
dmq1 = d% (q – 1)
iqmp = pow(q, -1, p)
# Assemble the non-public key object
private_numbers = rsa.RSAPrivateNumbers(
p=p, q=q, d=d, dmp1=dmp1, dmq1=dmq1, iqmp=iqmp,
public_numbers=rsa.RSAPublicNumbers(e=e, n=n)
)
private_numbers.private_key(), return n, d
if __name__ == “__main__”:
# – enter –
p = 997
q = 881
e = 65537
# Generate the important thing and get the calculated quantity
key, n, d = create_rsa_from_primes(p, q, e)
# — Export to PEM format —
private_pem = key.private_bytes(
encoding = serialization.encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
Encryption algorithm = serialization.NoEncryption()
)
public_pem = key.public_key().public_bytes(
encoding = serialization.encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
# — Print all —
print(“=== RSA Key Part (Calculation) ===”)
print(f”prime number one (p): {p}”)
print(f”prime quantity 2 (q): {q}”)
print(f”modulus (n = p*q): {n}”)
print(f”Public index (e): {e}”)
print(f”Non-public index (d): {d}”)
print(“-” * 40)
print(“n— RSA non-public key (PEM) —”)
print(private_pem.decode())
print(“— RSA public key (PEM) —”)
print(public_pem.decode())
I hope this helps. Thanks for studying.
Additionally learn: Be taught to code at dwelling, CPU clock cycles, and one of the best Roblox coding books for youths

