Use cases
- Store private and public keys as files
Installation
Install cryptography
with pip
: pip install cryptorgraphy
Supported Python versions
- Python 2.7
- Python 3.6
- Python 3.7
Example Code for Python based asymmetric key storage using PEM serialization
import logging
from random import SystemRandom
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
# set up logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def demonstrate_asymmetric_key_storage(password=""):
"""
Example for key storage of a asymmetric key in one method.
- Random password generation using strong secure random number generator
- Generation of public and private RSA 4096 bit keypair
- Serialization of the private key using PEM encoding, PKCS8 format and a password
- Serialization of the public key using PEM encoding and Subject Public Key Info
- Writing and loading of the keys
- Exception handling
"""
try:
# GENERATE password (not needed if you have a password already)
if not password:
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
password = "".join(SystemRandom().choice(alphabet) for _ in range(20))
logger.info(password)
password_bytes = password.encode('utf-8')
# GENERATE NEW KEYPAIR
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
backend=default_backend()
)
public_key = private_key.public_key()
# SERIALIZATION
pem_private = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(password_bytes)
)
pem_public = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
# WRITE KEYS
with open("res/private_key.pem", 'wb') as key_file:
key_file.write(pem_private)
with open("res/public_key.pem", 'wb') as key_file:
key_file.write(pem_public)
# LOAD KEYS
with open("res/private_key.pem", "rb") as key_file:
private_key_after = serialization.load_pem_private_key(
data=key_file.read(),
password=password_bytes,
backend=default_backend()
)
with open("res/public_key.pem", "rb") as key_file:
public_key_after = serialization.load_pem_public_key(
data=key_file.read(),
backend=default_backend()
)
# CHECK whether keys are the same
private_before = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
private_after = private_key_after.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
public_before = pem_public
public_after = public_key_after.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
logger.info("Private Key before and after storage is the same: %s",
private_before == private_after)
logger.info("Public Key before and after storage is the same: %s",
public_before == public_after)
except (UnsupportedAlgorithm, ValueError, TypeError):
logger.exception("Asymmetric key storage failed")
if __name__ == '__main__':
# demonstrate method
demonstrate_asymmetric_key_storage("")