icon

satoshi.ke

Public Key Encryption
Published on Jan 25, 2024 11:43 by satoshiken

Table of Contents

1. Introduction

In a previous article, we discussed symmetric encryption. In this article we'll take a look at asymmetric encryption which is also known as public key cryptography.

In symmetric encryption, the same secret key is used for both encoding and decoding messages. However, as we discussed in the previous article, transmitting this secret key securely can be a challenge.

Public key cryptography is one solution to this problem. It involves the use of two keys: a public key, which is openly accessible, and a private key, which is kept secret.

The two keys are mathematically linked, plaintext encrypted with a user's the public key can only be decrypted with their corresponding private key. Likewise, plaintext signed with the user's private key can only be verified with the corresponding public key.

The former is used in a public key encryption system, and will be the subject of this article. The latter is used in a digital signature system which will be discussed in the next article.

(Update: Article on digital signatures published here)

2. Public Key Encryption

In a public key encryption system, participants distribute their public keys freely but keep their private keys secret. Anyone who wants to send a message to a recipient will encrypt it using their public key. Only the private key can be used to decrypt the resulting ciphertext and as long as the recipient keeps their private key secret, only they can decrypt the message.

public_key_encryption.png

Figure 1: illustration of public key encryption

There are different types of algorithms that are used to implement public key encryption. In general, their security relies on the mathematical properties that can be used to design puzzles that are too computationally demanding to solve as they lack a known efficient solution.

For example, one of the pioneering techniques known as RSA relies on the fact that it is extremely difficult to factorize large integer numbers.

Because public key encryption is computationally intensive, in situations where lengthy messages or frequently exchanged messages need to be encrypted, public key encryption is used to initially send a secret key to the recipient. Subsequent communication can then more efficiently use the shared secret key for symmetric encryption.

2.1. Uses

Some uses of public key encryption:

  • Issuing and validation of certificates used to establish secure web communication via SSL/TLS
  • Encrypted email communication technologies such as PGP rely on public key encryption.
  • Secure messaging services like Signal and WhatsApp utilize public key encryption to exchange secure session tokens for encrypted communication.

2.2. Examples in code

These are basic examples in Python and JavaScript for the purpose of illustration.

2.2.1. Python

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

plaintext_in = "The quick brown fox jumps over the lazy dog"


def encrypt(plaintext, public_key):
    return public_key.encrypt(
        plaintext,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None,
        ),
    )


ciphertext = encrypt(bytes(plaintext_in, "utf-8"), public_key)


def decrypt(ciphertext, private_key):
    return private_key.decrypt(
        ciphertext,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None,
        ),
    )


bytes_out = decrypt(ciphertext, private_key)
plaintext_out = bytes_out.decode("utf-8")

assert plaintext_in == plaintext_out  # should be equal

In python, we use the third party library cryptography that can be installed via:

pip install cryptography

The first step is generating a recipient's public/private key pair using the RSA algorithm. We then encrypt the plaintext using the public key and finally decrypt the ciphertext using the private key.

Additional parameters required for the RSA such as public exponent, key size and padding are also chosen to be common ones. One has to be careful adjusting these and a detailed understanding of the underlying algorithms is required.

2.2.2. JavaScript

const { 
    generateKeyPairSync,
    publicEncrypt,
    privateDecrypt,
    constants
} = await import("node:crypto");

const { publicKey, privateKey } = generateKeyPairSync('rsa', {
    publicExponent: 65537,
    modulusLength: 2048,
});

let plaintextIn = "The quick brown fox jumps over the lazy dog";

const encrypt = (plaintextBytes, publicKey) => {
    return publicEncrypt({
        key: publicKey,
        padding: constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: 'sha256',
    }, plaintextBytes);
};

let ciphertext = encrypt(Buffer.from(plaintextIn), publicKey);

const decrypt = (ciphertext, privateKey) => {
    return privateDecrypt({
        key: privateKey,
        padding: constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: 'sha256',
    }, ciphertext);
};

let bytesOut = decrypt(ciphertext, privateKey);
let plaintextOut = bytesOut.toString();

console.assert(plaintextIn == plaintextOut); // should pass

In JavaScript, we use the crypto module that by default ships with Node.js.

Similar to the Python example, we first generate a key pair, then encrypt with the public key and decrypt with the private key.

3. Conclusion

In this article we discussed a facet of asymmetric encryption, public key encryption, which is used for secure exchange of secrets with only knowledge of the recipient's public key required. We saw how it can be used to exchange a shared secret key to allow two parties to communicate securely over an insecure channel using the less computationally intensive symmetric encryption.

Simplified code samples are provided in Python and JavaScript demonstrating public key encryption.

In a follow up article, we will discuss the other facet of asymmetric encryption, digital signatures.

For a more in-depth exploration, check out the CRYPTO101 course and the Cryptopals challenge.