There are various one-way functions that can be used for this purpose, but in RSA, the function is factoring a large number:
- Private key d is made from two large prime numbers: p and q
- Public key is the product of n = p * q, and and arbitrary value e
- If p and q are large, factoring n into p and q is very difficult
If you multiply the two prime numbers p and q together to create their product n, it is a well-known difficult problem to factor n into p and q. And if p and q are large enough, it becomes essentially impossible. This is the one-way function. You can easily multiply p and q to create the public key n, but knowledge of the public key cannot be used to determine p and q practically:
- Public key: This is two numbers, (n,e)
- e can be any prime number, often 65537
- Encryption: y = xe mod n
- Decryption: x = yd mod n
- x is plaintext, y is ciphertext
So, the public key is n, which is the product of two prime numbers and another arbitrary number, e, which is often just this value 65,537. Anyone who wishes to secretly send their plaintext, x, raises it to the power of e, modulus n, and sends that scrambled stuff over an insecure channel, such as the internet, to the recipient. The recipient has the private key so they can find the decryption key, d, and they take the ciphertext to d modulus n, and that turns into the decrypted message. The decryption key is calculated this way:
- phin = (p-1) * (q-1)
- d*e = 1 mod phin
Since Google knows the p and q secrets, they can calculate this number phin which is p - 1, times q - 1 and then they choose a decryption key so that d times e is 1 modulus Phi of n. Nobody else can do this calculation because they do not know the values of p and q. So, in Python, you can import the RSA module and then generate a key of whatever length you like. In this example, we have used 2048 bits, which is the current National Institute of Standards recommendation. Then, they have a public key. There's a message to encrypt and you encrypt it, and the result is this very long ciphertext, which is as long as 2048 bits. ciphertext is long and the calculations are very slow, so you do not normally send a long message with this method. What you do in RSA is just send a secret key, and then you use AES to encrypt everything after that point to make the calculations faster. This chapter covers something called textbook RSA, which contains many of the essential ingredients but is not really secure enough for real use, because you have to add a padding that is specified in RFC 8017. This adds a hash value, a mask, and padding to the message and protects the key from some attacks. Let's take a look at this in Python.