I am currently undertaking the “Encryption & Cryptography” course on FutureLearn (https://www.futurelearn.com/courses/encryption-and-cryptography/ ) and looking at public-key cryptography, specifically today the RSA public-key method.
RSA is named after Ron Rivest, Adi Shamir and Leonard Adleman (Rivest-Shamir-Adleman; RSA) and the details for the algorithm were first published in 1977. English mathematician, Clifford Cocks developed a similar system in 1973 however his work was classified by GCHQ until 1997.
RSA is an asymmetrical encryption algorithm that relies on prime numbers, the larger the prime number the better for cryptography.
I originally took a look at creating RSA keys on Christmas Eve (my original Python is here in my GitHub) but found later steps in the course include creating RSA keys in Python and a few hints.
Part of the “Encryption & Cryptography” course is to generate an 8-bit RSA key using Python:
Generating an 8bit RSA key in Python
—
# RSA
# GeekTechStuff
from sympy import randprime, isprime
def create_rsa_r_8():
# Generates an 8-bit key
p = 0
q = 0
r = 257
while r > 256:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
if p == q:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
# RSA modulus (R) of both primes (p * q)
r = p * q
# Euler’s totient
e = (p-1)*(q-1)
print(“Euler = “,e)
return(r)
rsa = create_rsa_r_8()
print(“RSA modulus (r) = “,rsa)
—
Sympy can be installed using pip3:
pip3 install sympy
pip3 install sympy
Amendment (30th December 2019):
Ever have one of those “Doh!” moments? I now can see why my original RSA attempt failed, I was using the values of the alphabet like in a Caesar cipher and not the ASCII values.
With my 8-bit RSA key generator working the next part of the course requires that it encrypts and decrypts a letter. I’ve amended the code in my GitHub (https://github.com/geektechdude/Python_Encryption/blob/master/geektechstuff_rsa.py ) to show this version.
—
# RSA
# GeekTechStuff
from sympy import randprime, isprime
# Generates an 8-bit key
p = 0
q = 0
r = 257
while r > 256:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
if p == q:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
# RSA modulus (R) of both primes (p * q)
r = p * q
print(“RSA(r) = “,r)
# Euler’s totient
e = (p-1)*(q-1)
print(“Euler = “,e)
# Public key – relative prime, greater than 1 and less than Euler’s totient
pub_key = randprime(2,e)
print(“Public Key: “,pub_key)
# Private key generation
d = 0
while d < 1000000000:
if (pub_key * d) % e == 1:
break
d = d+1
priv_key = d
print(“Private Key: “,priv_key)
# Trying above to encrypt ASCII A
print(“Converting A to its ASCII value”)
ascii = ord(“A”)
print(“ASCII value of A is: “,ascii)
print(“Attempting to encrypt A”)
m = ascii
cipher_text = (m**pub_key)%r
print(“(“,m,”**”,pub_key,”) %”,r )
print(“Ciphered letter becomes ASCII:”,cipher_text)
c = cipher_text
decrypt_text = (c**priv_key)%r
print(“(“,c,”**”,priv_key,”) %”,r)
print(“Decrypted letter becomes ASCII:”,decrypt_text)
if m == decrypt_text:
print(“Success!!”)
—
30th Dec’s attempt at 8bit RSA key generation Part 1
30th Dec’s attempt at 8bit RSA key generation Part 2
My Python program successfully encrypts ASCII A (65) to a different value (41) and back again.
I have added a function to encrypt and a function to decrypt a message:
—–
# RSA
# GeekTechStuff
from sympy import randprime, isprime
# Generates an 8-bit key
p = 0
q = 0
r = 257
while r > 256:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
if p == q:
# 1st prime (p)
p = randprime(2,250)
# 2nd prime (q)
q = randprime(2,250)
# RSA modulus (R) of both primes (p * q)
r = p * q
print(“RSA(r) = “,r)
# Euler’s totient
e = (p-1)*(q-1)
print(“Euler = “,e)
# Public key – relative prime, greater than 1 and less than Euler’s totient
pub_key = randprime(2,e)
print(“Public Key: “,pub_key)
# Private key generation
d = 0
while d < 1000000000:
if (pub_key * d) % e == 1:
break
d = d+1
priv_key = d
print(“Private Key: “,priv_key)
# Trying above to encrypt ASCII A
print(“Converting A to its ASCII value”)
ascii = ord(“A”)
print(“ASCII value of A is: “,ascii)
print(“Attempting to encrypt A”)
m = ascii
cipher_text = (m**pub_key)%r
print(“(“,m,”**”,pub_key,”) %”,r )
print(“Ciphered letter becomes ASCII:”,cipher_text)
c = cipher_text
decrypt_text = (c**priv_key)%r
print(“(“,c,”**”,priv_key,”) %”,r)
print(“Decrypted letter becomes ASCII:”,decrypt_text)
if m == decrypt_text:
print(“Success!!”)
def cipher_message(message):
encrypt_text = []
for letter in message:
m = ord(letter)
cipher_text = (m**pub_key)%r
encrypt_text.append(cipher_text)
print(encrypt_text)
return(encrypt_text)
def decrypt_message(message):
decrypt_text = “”
for letter in message:
c = letter
decrypt_letter = (c**priv_key)%r
ascii_convert = chr(decrypt_letter)
decrypt_text = decrypt_text + ascii_convert
print(decrypt_text)
return(decrypt_text)
# Testing
test = cipher_message(“geektechstuff is an awesome website”)
decrypt_message(test)
—–
Encrypt / Decrypt function
Example of the RSA python program in action
More Information:
RSA at Wikipedia:
https://en.wikipedia.org/wiki/RSA_(cryptosystem)
Prime Numbers at Wikipedia:
https://en.wikipedia.org/wiki/Prime_number
Published by Geek_Dude
I'm a tech enthusiast that enjoys science, science fiction, comics and video games - pretty much anything geeky.
View all posts by Geek_Dude
One thought on “RSA Public-Key Cryptography (Python)”
Comments are closed.