Of course! In Python, the standard library for cryptographic operations, including RSA, is cryptography. The cryptography library provides high-level recipes and low-level interfaces for common cryptographic algorithms.

When you talk about importing an RSA key, you usually mean loading it from a standard format. The two most common formats are:
- PEM (Privacy-Enhanced Mail): A base64-encoded format that is often wrapped with
-----BEGIN...and-----END...headers. This is the most common format for storing keys in files. - DER (Distinguished Encoding Rules): A binary format. It's not human-readable and is often used in certificates and network protocols.
Here’s a complete guide on how to import RSA keys using the cryptography library.
Step 1: Install the cryptography Library
If you don't have it installed, open your terminal or command prompt and run:
pip install cryptography
Step 2: Importing a Private Key
Private keys can be in either PEM or DER format.

A. Importing a PEM-formatted Private Key
This is the most frequent use case. A PEM private key file looks like this:
private_key.pem
-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAy3f6Q8ZJ8k0Y2QJqG5p6y7a8b9c0d1e2f3a4b5c6d7e8f9a0b1 c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3 ... (a lot of base64 data) ... -----END RSA PRIVATE KEY-----
Python Code to Import:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
import os
# --- Create a dummy private key file for demonstration ---
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
)
with open("private_key.pem", "wb") as f:
f.write(pem)
# --- End of dummy file creation ---
# --- The actual import process ---
try:
with open("private_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None, # Set to None if no password, or provide the password as bytes
backend=default_backend()
)
print("Successfully loaded private key!")
print(f"Private Key Type: {type(private_key)}")
print(f"Key Size: {private_key.key_size} bits")
except ValueError as e:
print(f"Error loading private key: {e}")
print("This often means the key is corrupted or the password is wrong.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# Clean up the dummy file
os.remove("private_key.pem")
Explanation:

serialization.load_pem_private_key(): This is the function to load a private key from a PEM-encoded byte string.key_file.read(): Reads the entire content of the file.password=None: If your private key is encrypted with a passphrase (which is good practice!), you need to provide it here as bytes, e.g.,password=b'my_secret_password'. If it's not encrypted, useNone.backend=default_backend(): Specifies the backend to use.default_backend()is fine for most cases.
B. Importing a DER-formatted Private Key
A DER file is binary. The process is very similar, you just use load_der_private_key().
Python Code to Import:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
import os
# --- Create a dummy DER private key file for demonstration ---
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
der = private_key.private_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with open("private_key.der", "wb") as f:
f.write(der)
# --- End of dummy file creation ---
# --- The actual import process ---
try:
with open("private_key.der", "rb") as key_file:
private_key = serialization.load_der_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
print("Successfully loaded private key from DER format!")
print(f"Private Key Type: {type(private_key)}")
except ValueError as e:
print(f"Error loading private key: {e}")
# Clean up the dummy file
os.remove("private_key.der")
Step 3: Importing a Public Key
Public keys are also stored in PEM or DER formats. A PEM public key file looks like this:
public_key.pem
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3f6Q8ZJ8k0Y2QJqG5p6y7 a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0 d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3 ... (a lot of base64 data) ... -----END PUBLIC KEY-----
Python Code to Import:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
import os
# --- Create a dummy public key file for demonstration ---
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open("public_key.pem", "wb") as f:
f.write(pem)
# --- End of dummy file creation ---
# --- The actual import process ---
try:
with open("public_key.pem", "rb") as key_file:
public_key = serialization.load_pem_public_key(
key_file.read(),
backend=default_backend()
)
print("Successfully loaded public key!")
print(f"Public Key Type: {type(public_key)}")
print(f"Key Size: {public_key.key_size} bits")
except ValueError as e:
print(f"Error loading public key: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# Clean up the dummy file
os.remove("public_key.pem")
Explanation:
serialization.load_pem_public_key(): The function for loading a public key from PEM format.- There is no
passwordargument for public keys, as they are not typically encrypted. - For DER format, you would use
serialization.load_der_public_key().
Common Error and Solution: TypeError: Object type ...
A very common error when working with keys is a TypeError during import, especially when you have a key that you think is a private key but might be a public key.
The Problem:
You try to load a key with load_pem_private_key(), but the file actually contains a public key.
# This will FAIL with a TypeError if public_key.pem is loaded as a private key
with open("public_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(key_file.read(), password=None)
# TypeError: Object type public_key, private_key expected
The Solution:
The cryptography library provides a smart loader, load_pem_key(), which tries to intelligently determine whether the PEM data represents a public or private key. This is often the safest and most convenient function to use.
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
# This will work for BOTH private_key.pem and public_key.pem
with open("public_key.pem", "rb") as key_file: 