Digital Signatures
debt(d7/e5/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). While semgrep is listed as a detection tool, automated detection is marked 'no'. Misuse patterns like using HMAC where non-repudiation is required or using weak hash algorithms typically require careful code review to identify — there's no compiler error for choosing MD5 over SHA256, and the signature will appear to work until cryptographic weaknesses are exploited.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix suggests switching to openssl_sign() with OPENSSL_ALGO_SHA256, but common mistakes like 'signing the wrong data' or 'not verifying the certificate chain' require refactoring verification logic across multiple touchpoints. Replacing HMAC with proper asymmetric signatures where non-repudiation is needed affects key management, distribution, and verification across the system.
Closest to 'persistent productivity tax' (b5). Digital signatures apply across web and cli contexts and underpin JWTs, webhooks, and code signing. The choice of signing algorithm, key management strategy, and verification approach creates a persistent tax — every new integration point must handle signatures consistently, and the asymmetric key infrastructure must be maintained across the system's lifetime.
Closest to 'serious trap' (t7). The misconception explicitly states developers confuse digital signatures with encryption for confidentiality, when they only prove integrity and authenticity. Additionally, confusing HMAC (symmetric) with digital signatures (asymmetric) is listed as a common mistake — this contradicts how similar-looking cryptographic operations work, and developers familiar with HMAC may incorrectly assume both parties need the same key.
Also Known As
TL;DR
Explanation
Signing: hash the data, encrypt the hash with the private key. Verification: decrypt the signature with the public key, hash the data independently, compare. If they match, the data is authentic and unmodified. Ed25519 is the modern recommended algorithm — faster and more secure than RSA signing. Used in: TLS certificates, JWT signing, Git signed commits, code signing, and API request authentication. Non-repudiation means the signer cannot deny having signed.
Diagram
sequenceDiagram
participant SIGNER as Signer
participant MSG as Message
participant VERIFIER as Verifier
SIGNER->>MSG: hash the message
SIGNER->>SIGNER: encrypt hash with private key
SIGNER->>VERIFIER: send message + signature
VERIFIER->>VERIFIER: hash received message
VERIFIER->>VERIFIER: decrypt signature with public key
VERIFIER->>VERIFIER: compare hashes
Note over VERIFIER: Hashes match = authentic + untampered
Note over VERIFIER: Hashes differ = tampered or wrong key
Common Misconception
Why It Matters
Common Mistakes
- Using weak hash algorithms (MD5, SHA1) for signing — collision attacks allow forged signatures.
- Signing the wrong data — sign the canonical form of the data, not a developer-friendly representation.
- Not verifying the certificate chain when verifying a signature — the public key must be trusted.
- Confusing HMAC (symmetric shared secret) with digital signatures (asymmetric) — HMAC requires both parties to have the secret.
Code Examples
// Weak signing — SHA1 hash, vulnerable to collisions:
$signature = openssl_sign($data, $sig, $privateKey, OPENSSL_ALGO_SHA1);
// JWT signature verification skipped:
$payload = json_decode(base64_decode(explode('.', $jwt)[1]));
// Using payload without verifying signature — unsigned claims trusted
// Ed25519 signature with PHP:
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// Verify:
$valid = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256) === 1;
if (!$valid) throw new SecurityException('Invalid signature');
// HMAC for webhook verification (symmetric):
$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $receivedSig)) throw new SecurityException('Bad signature');