from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
def create_rsa_signature(m: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
return private_key.sign(
=m,
data=padding.PSS(
padding=padding.MGF1(hashes.SHA256()),
mgf=padding.PSS.MAX_LENGTH,
salt_length
),=hashes.SHA256(),
algorithm
)
def verify_rsa_signature(m: bytes, public_key: rsa.RSAPublicKey, sig: bytes) -> None:
'''Throws InvalidSignature, if sig is not valid.'''
public_key.verify(=sig,
signature=m,
data=padding.PSS(
padding=padding.MGF1(hashes.SHA256()),
mgf=padding.PSS.MAX_LENGTH,
salt_length
),=hashes.SHA256(),
algorithm )
5.8 RSA RETURNS!
EXERCISE 5.8: RSA RETURNS
Create an encryption and authentication system for Alice, Bob, and EATSA. This system needs to be able to generate key pairs and save them to disk under different operator names. To send a message, it needs to load a private key of the operator and a public key of the recipient. The message to be sent is then signed by the operator’s private key. Then the concatenation of the sender’s name, the message, and the signature is encrypted.
To receive a message, the system loads the private key of the operator and decrypts the data extracting the sender’s name, the message, and the signature. The sender’s public key is loaded to verify the signature over the message.
You can reuse the rsa_encrypt(m: bytes, public_key: rsa.RSAPublicKey)
and rsa_decrypt(c: bytes, private_key: rsa.RSAPrivateKey)
functions from exercise 4.11.
You can use the following functions for creating and verifying the signatures:
You can use the following functions to read/write the keys from the hard disk:
from cryptography.hazmat.primitives import serialization
import os.path
def read_public_key_from_file(fname: str) -> rsa.RSAPublicKey:
if not os.path.exists(fname):
raise FileNotFoundError()
with open(fname, 'rb') as f:
= serialization.load_pem_public_key(
public_key =f.read(),
data=default_backend(),
backend
)return public_key
def read_private_key_from_file(fname: str) -> rsa.RSAPrivateKey:
if not os.path.exists(fname):
raise FileNotFoundError()
with open(fname, 'rb') as f:
= serialization.load_pem_private_key(
private_key =f.read(),
data=default_backend(),
backend=None,
password
)return private_key
def write_public_key_to_file(fname: str, public_key: rsa.RSAPublicKey) -> None:
with open(fname, 'wb') as f:
f.write(
public_key.public_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PublicFormat.SubjectPublicKeyInfo,
)
)
def write_private_key_to_file(fname: str, private_key: rsa.RSAPrivateKey) -> None:
with open(fname, 'wb') as f:
f.write(
private_key.private_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PrivateFormat.TraditionalOpenSSL,
=serialization.NoEncryption(),
encryption_algorithm
) )