Experimenting
with RSA digital signatures:
· Digital Signatures are built on top
of Public Key Cryptography.
· The signer: The signature is generated using the
signer’s private key.
· The verifier uses the signer’s public key to verify the
signature and the original message.
Figure
1: Bob uses his own private key to generate a digital signature from a given
message (originally Figure 5.2 from the book)
Q1:
To generate a digital signature, what
are the needed components?
Your answer?
Q2:
In signing a document, is a
ciphertext part of the output?
Your answer?
Figure
2: Alice (or anyone else) could use Bob’s public key
to verify the message and the signature (originally Figure 5.3 from the book)
Q3:
To verify a digital signature, what
are the needed components?
Your answer?
Q4:
What is the output of the signature
verification process?
Your answer?
· Corrections of errors of codes in the book:
Figure
3: Correction of some errors of codes from the textbook
Exercises
Step 1: To
generate an RSA key pair for Bob.
Review Figure 1 of Experimenting
with Asymmetric Encryption and Decryption using RSA keys.
Step
2: Bob uses his private key to sign a message, and makes the message and the
signature available for verification.
# script: BobSign.py from cryptography.hazmat.primitives
import hashes from
cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.backends
import default_backend from cryptography.hazmat.primitives
import serialization import json # Deserialization of Bob's private key with open('private_key.pem', 'rb') as
private_file: loaded_private_key = serialization.load_pem_private_key( private_file.read(), password=None, backend=default_backend() ) # Use PSS padding when signing data; # Use OAEP when encrypting data. padding_config = padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH) message = b'message to be signed by
Bob' private_key = loaded_private_key signature = private_key.sign( message, padding_config, hashes.SHA256()) signed_msg = { 'message': list(message), 'signature': list(signature), } outbound_msg_to_alice =
json.dumps(signed_msg) # Save the signed message into a
separate signed.dat file. with open('signed.dat', 'wb') as
signed_file:
signed_file.write(outbound_msg_to_alice.encode()) print("signed mesg and signature
in 'signed.dat'.") |
Figure
4: Signing a message
Step
3: Alice uses Bob’s public key to verify the signature and the message.
# script: BobVerify.py from cryptography.hazmat.primitives
import hashes from cryptography.hazmat.primitives.asymmetric
import padding from cryptography.hazmat.backends
import default_backend from cryptography.hazmat.primitives
import serialization import hashlib import json from cryptography.exceptions import
InvalidSignature # Read the signed_mesg file with open('signed.dat', 'rb') as
signed_file: inbound_msg_from_bob
= signed_file.read() signed_msg =
json.loads(inbound_msg_from_bob) message = bytes(signed_msg['message']) signature =
bytes(signed_msg['signature']) # Deserialization of Bob's public key with open('public_key.pem', 'rb') as
public_file: loaded_public_key =
serialization.load_pem_public_key( public_file.read(), backend=default_backend() ) padding_config = padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH) ## NOTE: Errors of codes in the book public_key = loaded_public_key try: public_key.verify( ## NOTE: Errors of codes
in the book
signature,
message,
padding_config,
hashes.SHA256()) print('Trust message') except InvalidSignature: print('Do not trust message') |
Figure
5: Signature Verification
Step
4: As shown in Figure 6, run both programs to verify the signature.
Figure
6: Run the BobSign.py and AliceVerify.py programs
Step
5: Save signed.dat to signed2.dat. Change the first byte in signed.dat from 109
to 111. Then run AliceVerify.py to see how it would work.
· Food for
thought ...
Qa: Does
digital signature provide confidentiality?
Qb: What
security services are provided by using digital signatures?
Qc: How
would you add confidentiality to the above programs?