A digital signature isn’t just an electronic scribble; it’s a cryptographic guarantee that proves a message came from who it says it came from and hasn’t been tampered with.
Let’s see one in action. Imagine Alice wants to send a sensitive document to Bob. She’ll use her private key to create a digital signature for that document.
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
# Alice generates a key pair
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
public_key = private_key.public_key()
# Alice's document
document = b"This is the confidential report for Q3."
# 1. Sign the document
signature = private_key.sign(
document,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print(f"Original Document: {document.decode()}")
print(f"Digital Signature (hex): {signature.hex()}")
# Bob receives the document and the signature.
# Bob needs Alice's public key to verify.
# 2. Verify the signature
try:
public_key.verify(
signature,
document,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("Signature is valid. The document is authentic and unaltered.")
except Exception as e: # In a real scenario, you'd catch InvalidSignature
print(f"Signature is invalid: {e}")
# What if the document was tampered with?
tampered_document = b"This is the confidential report for Q4. (REVISED)"
try:
public_key.verify(
signature, # Using the ORIGINAL signature
tampered_document, # Using the TAMPERED document
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("Signature is valid. (This should not happen if tampered!)")
except Exception as e:
print(f"Signature is invalid for tampered document: {e}")
This process hinges on asymmetric cryptography, specifically public-key pairs. Alice uses her private key for signing and Bob uses Alice’s public key for verification. The magic is that a signature created with a private key can only be verified by its corresponding public key.
At its core, signing involves two steps. First, a cryptographic hash of the document is generated. This hash is a fixed-size fingerprint, so even a tiny change in the document results in a completely different hash. Think of it like creating a unique checksum. Second, this hash is encrypted using Alice’s private key. This encrypted hash is the digital signature.
Verification reverses this. Bob calculates the hash of the document he received. Then, he decrypts the signature using Alice’s public key. If the decrypted hash from the signature matches the hash he calculated from the document, he knows two things: the signature was indeed created by Alice’s private key (because only her public key could decrypt it correctly), and the document hasn’t changed since it was signed (because the hashes match).
The "trust" aspect comes into play when Bob needs to be sure that the public key he’s using actually belongs to Alice. This is where Certificate Authorities (CAs) and Public Key Infrastructure (PKI) become crucial. A CA is a trusted third party that verifies the identity of individuals or organizations and then issues a digital certificate binding their identity to their public key. When you visit a secure website (HTTPS), your browser checks the website’s certificate, which was issued by a CA, to ensure you’re communicating with the legitimate server and not an imposter.
The padding scheme (like PSS in the example) and the hashing algorithm (like SHA256) are critical components that ensure the security and integrity of the signature process. Different padding schemes offer varying levels of security against specific attacks. The hash function must be collision-resistant, meaning it’s computationally infeasible to find two different inputs that produce the same hash output.
When you see a digital signature in practice, it’s often not the raw signature bytes but a certificate that contains the public key and information about its owner, signed by a trusted CA. The verification process involves not only checking the signature against the document but also validating the certificate’s chain of trust back to a root CA that your system already trusts.
A common pitfall is assuming that just because you have a public key, it’s the correct public key for the person you think it is. The security of digital signatures is a chain, and a weak link in that chain – like using a public key that was compromised or mistakenly associated with the wrong entity – breaks the entire system.
The next step in understanding this is exploring how key management systems automate the distribution and revocation of these public keys and certificates.