The first step of the encryption process is to generate the mathematically linked keys. Before continuing, it should be mentioned that the public key is in fact two values: the "key" value, and an "exponent" value. The exponent is required both in the generation of the keys as well as the data encryption.
import obj
import mmi
from math import gcd
Three inputs are required for the generation of the RSA keys. Two prime numbers and an exponent value. Larger primes are more secure, and the exponent must meet multiple criteria.
def generateKeys (primeA, primeB, exponent):
# Generate public key
key_public = primeA * primeB
# Calculate phi
phi = (primeA - 1) * (primeB - 1)
# Determine if exponent value passes four tests:
# Is integer?
if int(exponent) != exponent:
return 'ERROR: Exponent must be an integer.'
# Is greater than 1?
elif 1 >= exponent:
return 'ERROR: Exponent must be greater than 1.'
# Is less than phi?
elif exponent >= phi:
return 'ERROR: Exponent must be less than phi.'
# Is coprime with phi?
elif gcd(exponent,phi) != 1:
return 'ERROR: Exponent may not share factors with phi.'
# Generate private key (modular multiplicative inverse)
key_private = mmi.modinv(exponent, phi)
# Return keys
return {
"key_public" : key_public,
"key_private": key_private,
"exponent" : exponent
}
For the sake of practicality, relatively small prime values will be used. The resulting keys are 6 digits in length, but very strong modern keys can be 600 digits long!
primeA = 523
primeB = 541
exponent = 17
keys = generateKeys(primeA, primeB, exponent)
print(keys)
obj.save(keys, 'data/keys')