1. Home
  2. Cryptography & Network Security
  3. Digital Signatures

Digital Signatures

Prove who wrote a message and that nobody changed it. Alice hashes and signs with her private key, Bob verifies with her public key, and Eve's tampering and forgery both fail, in 3D.

Interactive 3DIntermediate12 min readCNSUpdated

Drag to rotate · Right-drag to pan · Click, then scroll to zoom · Space play · ←→ step

What's happening

Pseudocode

    Try this in the 3D model

    • Press Sign and verify. Which key does Alice use, and which key does Bob use?
    • Press Tamper. How many of the 64 hex digits of the hash change when Eve edits one character?
    • Press Forge. Eve has a perfectly good key pair. Why does her signature still fail?
    • Type your own message and sign it. Change one letter in the box, then press Tamper to compare.

    A handwritten signature, but unforgeable

    A signature on paper says “I wrote this”, but it is easy to copy and doesn’t stop someone changing the text above it. A digital signature does better. It is a number computed from the message and a secret key, so it:

    Property Meaning
    Authenticity it was made by the owner of the private key
    Integrity the message hasn’t changed since it was signed
    Non-repudiation the signer can’t later deny it, because nobody else could have made it

    It does not hide the message. For secrecy, encrypt as well.

    Hash, then sign

    With RSA, Alice has a private key d and a public key (e, n). Signing is RSA used “backwards”:

    Alice:  h  = SHA-256(M)            fingerprint of the message
            s  = h^d mod n             sign with the PRIVATE key
            send (M, s)
    Bob:    h' = SHA-256(M)            hash what he received
            v  = s^e mod n             open the signature with Alice's PUBLIC key
            valid  if and only if  v = h'

    Why hash first? SHA-256 turns a message of any size into 256 bits, so one exponentiation signs a whole file. And because finding two messages with the same hash is infeasible, signing the hash is as good as signing the message.

    Worked example

    The model uses a toy key, p = 61 and q = 53, so n = 3233, e = 17 and d = 2753. Because n is tiny, the hash is reduced mod n first. Real keys have n of 2048 bits or more and sign the full hash with a padding scheme such as RSA-PSS.

    Step Value
    Message “Pay Bob 500”
    SHA-256 13e6e4ec…6df6bbf7
    h = hash mod 3233 2914
    s = 2914²⁷⁵³ mod 3233 2331
    Bob: 2331¹⁷ mod 3233 2914 = h′, so valid

    What happens if Eve interferes?

    • Tampering. Eve changes the text to “Pay Bob 900” and keeps s = 2331. Bob’s hash changes completely: h′ = 116. But the signature still opens to 2914, the hash of the original message. 2914 ≠ 116, so the signature is invalid.
    • Forgery. Eve signs her own message with her private key. Bob checks with Alice’s public key, and it doesn’t match. Without Alice’s private key, Eve can’t make a signature that Alice’s public key accepts. That would require breaking RSA.

    Where signatures are used

    • HTTPS certificates. A certificate authority signs “this public key belongs to example.com”, and your browser checks it.
    • Software updates and app stores. Your device installs only code signed by the developer.
    • Email (S/MIME, PGP), PDF documents, Git commits and India’s e-Sign.
    • Cryptocurrencies. Every transaction is signed. Bitcoin and Ethereum use ECDSA on elliptic curves rather than RSA.

    Code

    import hashlib
    
    n, e, d = 3233, 17, 2753          # toy RSA key: n = 61 x 53
    
    def h(message):
        """SHA-256 of the message, reduced mod n (real RSA signs the full padded hash)."""
        return int(hashlib.sha256(message.encode()).hexdigest(), 16) % n
    
    def sign(message):
        return pow(h(message), d, n)          # uses the PRIVATE key d
    
    def verify(message, s):
        return pow(s, e, n) == h(message)     # uses the PUBLIC key (e, n)
    
    s = sign('Pay Bob 500')
    print(s)                                  # 2331
    print(verify('Pay Bob 500', s))           # True
    print(verify('Pay Bob 900', s))           # False: the message was changed

    Common mistakes

    • Signing with the public key. You sign with your private key and verify with the public key. (Encryption is the other way round: encrypt with the receiver’s public key.)
    • Thinking a signature hides the message. It proves origin and integrity, not secrecy.
    • Signing without hashing (textbook RSA). Raw RSA signatures can be combined and forged. Always hash and pad.
    • Trusting any public key. A signature only proves the signer owns that key. Certificates are what link keys to real identities.

    Complexity at a glance

    Case / operationTimeWhy
    Hash the message (SHA-256)O(n)n = message length. The signature itself is then a fixed size.
    Sign (s = hᵈ mod n)O(k³) for a k-bit modulusSquare-and-multiply on k-bit numbers. Slower than verifying, because d is large.
    Verify (sᵉ mod n)faste is usually 65537 = 2¹⁶ + 1, so only 16 squarings and 1 multiplication.
    Forge without the private keyas hard as breaking RSA

    Quick check

    Test yourself — pick an answer to see if you got it.

    1. Which key does Alice use to create a digital signature?

    2. Why does Alice sign a hash of the message instead of the message itself?

    3. Eve changes one character of a signed message and keeps the signature. What happens when Bob verifies?

    4. Which property does a digital signature NOT give?

    5. How does Bob know that a public key really belongs to Alice?

    Saved in this browser.
    Spotted a mistake or a bug in the 3D model?

    Report a mistake

    in Digital Signatures. Thank you — every report makes the lesson better for the next reader.

    We'll also include a link to the step of the 3D model you're on and your browser type, so we can reproduce it.