Skillversitas

RSA Key Generation

RSA is the oldest widely used public-key system: a key pair derived from the product of two large primes, with the security resting on the difficulty of factoring that product. You generate a private key (both primes plus derived exponents) and export its public half (modulus and public exponent). Key size is the security dial: 2048 bits is the current minimum, 3072+ for long-lived keys.

Generating a Key Pair

from cryptography.hazmat.primitives.asymmetric import rsa

private_key = rsa.generate_private_key(
    public_exponent=65537,      # standard Fermat prime; fast public ops
    key_size=2048,              # 2048 minimum; 3072 for the long term
)

public_key = private_key.public_key()
print(private_key.key_size)     # 2048
print(public_key.public_numbers().e)   # 65537

Generation takes a noticeable second or more for 2048 bits because it must find two safe primes - generate keys once and store them, not per request.

Serializing Keys

Keys are objects; to store or send them you serialize. Two encodings exist: DER (binary) and PEM (base64 text with headers), and two structures: PKCS#8 for private keys and SubjectPublicKeyInfo for public keys.

from cryptography.hazmat.primitives import serialization

pem_private = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)
print(pem_private[:30])   # b'-----BEGIN PRIVATE KEY-----\nM...'

pem_public = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo,
)

# load them back
loaded = serialization.load_pem_private_key(pem_private, password=None)

Protecting the Private Key

from cryptography.hazmat.primitives.ciphers import AES

# encrypt the PEM with a passphrase (PBES2 + AES)
protected = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.BestAvailableEncryption(
        b"change-me-in-a-secret-manager"),
)

# load with the passphrase
key = serialization.load_pem_private_key(protected, password=b"change-me-in-a-secret-manager")

In practice the passphrase is a secret from your key store, and the file permissions on the key file should be 0600. The private key is the entire identity of the RSA pair - losing it loses every signature and decryption it performed.

Key Size Guidance

SizeSecurityUse
2048~112 bitsminimum for new keys
3072~128 bitslong-lived certificates, signatures
4096~140+ bitsvery long-lived or high-value keys

Summary

Generate 2048-bit (or larger) RSA keys with the standard 65537 exponent, export them as PKCS#8/SPKI in PEM, protect private keys with a secret-store passphrase and tight permissions, and size keys to how long they must stay secret.