Asymmetric cryptography¶
The asymmetric
module defines the functions for Asymmetric Cryptography or sometimes referred to as Public Key Cryptography. The functions publish_key
and fetch_key
manage publishing and retrieving of the public key to the PV080 server. They allow you to share your public key and retrieve the keys of other students.
For asymmetric cryptography we are using the Rivert-Shamir-Adleman (RSA) cryptosystem. The functions for encryption and decryption are rsa_encrypt
and rsa_decrypt
.
The asymmetric nature of RSA allows for the definition of digital signatures as well, therefore we have the function create_signature
for creating the digital signature and verify_signature
for verifying it.
All functions in the module work with RSA keys from the cryptography module, i.e. rsa.RSAPrivateKey and rsa.RSAPublicKey. To generate an RSA key pair, use the function rsa.generate_private_key and the member function rsa.RSAPrivateKey.public_key:
>>> from cryptography.hazmat.primitives.asymmetric import rsa
>>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
>>> public_key = private_key.public_key()
- pv080_crypto.asymmetric.publish_key(uco: int, key: RSAPublicKey) str [source]¶
Publishes the
key
under theuco
to https://pv080.fi.muni.cz/msg server, where it is readable by anyone on the internet.- Parameters:
uco – The UČO of the owner of the key.
key – The RSA public key of the owner.
- Returns:
The status message of the result of this API call to the server.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> publish_key(uco=408788, key=public_key) 'overwritten'
- pv080_crypto.asymmetric.fetch_key(uco: int) RSAPublicKey | None [source]¶
Fetches the public key associated with the
uco
from https://pv080.fi.muni.cz/msg.- Parameters:
uco – The UČO of the party we want to communicate with.
- Returns:
The
rsa.RSAPublicKey
corresponding touco
if found, otherwiseNone
.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> publish_key(uco=408788, key=public_key) 'overwritten' >>> assert isinstance(fetch_key(uco=408788), rsa.RSAPublicKey)
- pv080_crypto.asymmetric.rsa_encrypt(key: RSAPublicKey, plaintext: bytes) bytes [source]¶
Uses RSA public
key
to encrypt theplaintext
.- Parameters:
key – The RSA public key to use for the encryption.
plaintext – The plaintext bytes to be encrypted.
- Returns:
The ciphertext bytes.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> ciphertext = rsa_encrypt(key=public_key, plaintext=b"hello world")
- pv080_crypto.asymmetric.rsa_decrypt(key: RSAPrivateKey, ciphertext: bytes) bytes [source]¶
Use RSA private
key
to decrypt theciphertext
.- Parameters:
key – The RSA private key to use for the decryption.
ciphertext – The ciphertext bytes to be decrypted.
- Returns:
The plaintext bytes.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> ciphertext = rsa_encrypt(key=public_key, plaintext=b"hello world") >>> plaintext = rsa_decrypt(key=private_key, ciphertext=ciphertext) >>> assert b"hello world" == plaintext
- pv080_crypto.asymmetric.create_signature(private_key: RSAPrivateKey, data: bytes) bytes [source]¶
Use the RSA
private_key
to digitally sign thedata
.- Parameters:
private_key – The RSA private key to be used for signing.
data – The data to be signed.
- Returns:
The bytes of the signature.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> signature = create_signature(private_key=private_key, data=b"a contract contents")
- pv080_crypto.asymmetric.verify_signature(public_key: RSAPublicKey, data: bytes, signature: bytes) bool [source]¶
Verify that the
signature
ofdata
was signed using the RSAPrivateKey corresponding topublic_key
.- Parameters:
public_key – The
RSAPublicKey
to be used for the verification.data – The data that were signed.
signature – The bytes of the signature.
- Returns:
True
if thesignature
is a valid,False
otherwise.
Example:
>>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) >>> public_key = private_key.public_key() >>> data = b"the contract contents" >>> signature = create_signature(private_key=private_key, data=data) >>> assert verify_signature(public_key=public_key, data=data, signature=signature)