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)”