security/digital-signatures-how-a-message-proves-who-wrote-it-and-that-nobody-c.md

Digital signatures: how a message proves who wrote it and that nobody changed it

Security · 4 min read ·

How can you tell that a message really came from who it says, and that nobody changed a word on the way? A digital signature does both with a pair of keys: the private key makes the signature, the public key checks it.

Run a tiny RSA example in Python, then sign a message yourself in the page, change one character, and watch the check fail.

Two message cards: Pay Sam 10 dollars with a green check mark, and a changed Pay Sam 90 dollars with a red cross

You get a message that says "Pay Sam 10 dollars". Two things could be wrong with it. Somebody other than the sender might have written it, or somebody might have changed it on the way. A digital signature is a small number attached to a message that lets anyone check both things at once, without ever learning the sender's secret.

Two keys instead of one

Earlier we saw, in Diffie-Hellman, that strangers can build a shared secret in public. Signatures use a related idea called public-key cryptography: you make a pair of keys. The private key stays with you. The public key goes to everyone. The pair is built so that something done with the private key can be checked with the public key, but the public key can't be used to redo it.

Signing is that "something". Only the owner of the private key can produce a valid signature. Anyone holding the public key can verify it.

The recipe: hash, then lock

Signing a whole message directly would be slow, so the first step is to squeeze the message into a short fingerprint with a hash function (a recipe that turns any text into a fixed-size number, and gives a completely different number if even one character changes). Then the signer applies their private key to that fingerprint. The result is the signature.

To verify, the checker does two separate things: hash the message they received, and apply the public key to the signature. If the two numbers match, the message is untouched and it was signed by the matching private key.

A toy you can run

Real keys use numbers hundreds of digits long. To see the mechanism with your own eyes, here is RSA, one common signature scheme, with tiny numbers. This is for learning only: numbers this small can be broken in a blink, and real systems add padding rules this toy skips.

import hashlib
p, q = 61, 53
n = p * q                 # 3233, part of both keys
phi = (p - 1) * (q - 1)   # 3120
e = 17                    # public exponent
d = pow(e, -1, phi)       # 2753, the private key

def digest(msg):
    return int.from_bytes(hashlib.sha256(msg.encode()).digest(), "big") % n

def sign(msg):            # needs the private key d
    return pow(digest(msg), d, n)

def verify(msg, sig):     # needs only the public values e and n
    return pow(sig, e, n) == digest(msg)

s = sign("Pay Sam 10 dollars")
print(digest("Pay Sam 10 dollars"), s, verify("Pay Sam 10 dollars", s))
print(verify("Pay Sam 90 dollars", s))
print(verify("Pay Sam 10 dollars.", s))

Running it prints:

758 1848 True
False
False

The public key is the pair (e, n) = (17, 3233). The private key is d = 2753. pow(x, k, n) means "x multiplied by itself k times, keeping only the remainder after dividing by n". The signature 1848 is the fingerprint 758 raised to the private power; raising 1848 to the public power 17 brings 758 back.

Try it: forge a message

What a signature does not do

A signature does not hide the message. Anyone can still read it; encryption is a separate tool. It also only proves that the holder of a particular private key signed it. How you know that the public key really belongs to Sam is a different problem, and it's the one that HTTPS certificates solve: a trusted organisation signs a statement saying "this public key belongs to this website".

Where you meet this

Software updates are signed so your computer can reject a tampered download. Git can sign commits so others can see who made them. Websites present certificates so your browser can check it reached the right server. In each case the check is the same two-step: hash, then compare with what the public key reveals.

So what for your code

Never write your own signature scheme for real use. Use a well-reviewed library, keep private keys out of your code and out of Git, and remember that a failed verification means reject the message, no matter how reasonable it looks.

$ ls security/

see all →
security/csrf-why-a-request-carrying-your-cookie-isn-t-proof-that-you-sent-it.md CSRF: why a request carrying your cookie isn't proof that you sent it Log in to your bank in one tab, open a stranger's page in another, and a hidden form can make your browser send money. The attacker never… 6 min read · 31 Oct security/cross-site-scripting-how-a-comment-box-can-run-someone-else-s-code.md Cross-site scripting: how a comment box can run someone else's code A comment box looks harmless until someone types a tiny program instead of a comment. This article explains cross-site scripting, or XSS… 5 min read · 28 Oct security/two-factor-codes-how-your-phone-and-a-website-agree-on-six-digits-with.md Two-factor codes: how your phone and a website agree on six digits without talking Your authenticator app shows six digits and the website expects the same six, yet the two never talk. How? Both sides start from the same… 5 min read · 24 Oct security/sql-injection-how-a-quote-mark-in-a-login-form-can-rewrite-the-databas.md SQL injection: how a quote mark in a login form can rewrite the database's question A login form builds a database question out of the words you type. If it glues your text straight into the question, your text can rewrite… 5 min read · 21 Oct security/password-strength-why-length-beats-a-capital-letter-and-a-symbol.md Password strength: why length beats a capital letter and a symbol Everyone says passwords need a capital, a number and a symbol, and also that they should be long. Which one actually matters more? The… 6 min read · 18 Oct security/password-hashing-why-a-website-never-stores-your-password-and-what-a-s.md Password hashing: why a website never stores your password, and what a salt changes Websites should never store your password, only a hash made from it. But two users with the same password get the same hash, and a stolen… 5 min read · 15 Oct