CHAPTER 02

Digital Signatures and Cryptography

Mastering cryptographic foundations for content authentication and verification

Cryptographic Foundations

Digital signatures form the backbone of content authentication. They provide mathematical proof that content was created or endorsed by a specific entity and hasn't been altered since signing. Unlike physical signatures, digital signatures cannot be forged without access to the private key.

The security of digital signatures relies on asymmetric cryptography, where each entity possesses a key pair: a private key kept secret and a public key shared openly. Content signed with the private key can be verified by anyone with the corresponding public key.

Public Key Infrastructure (PKI)

PKI provides the framework for managing cryptographic keys and certificates. In content authentication:

// Example: Generating Ed25519 Key Pair
import { generateKeyPairSync } from 'crypto';

const { publicKey, privateKey } = generateKeyPairSync('ed25519', {
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});

console.log('Public Key:', publicKey);
console.log('Private Key:', privateKey);

// Store private key securely (e.g., hardware security module)
storeInHSM(privateKey);

// Publish public key for verification
publishPublicKey(publicKey);
            

Signature Algorithms

WIA-AI-017 supports multiple signature algorithms, each with different security properties and performance characteristics.

Ed25519 (Edwards-curve Digital Signature Algorithm)

Ed25519 is the recommended algorithm for most content authentication scenarios:

// Example: Signing Content with Ed25519
import { sign, createHash } from 'crypto';
import { readFileSync } from 'fs';

// Load content
const content = readFileSync('image.jpg');

// Hash the content first (best practice)
const contentHash = createHash('sha256').update(content).digest();

// Sign the hash
const signature = sign(null, contentHash, {
    key: privateKey,
    format: 'pem'
});

// Create authentication manifest
const manifest = {
    content_hash: contentHash.toString('hex'),
    signature: signature.toString('base64'),
    algorithm: 'Ed25519',
    signer_public_key: publicKey,
    timestamp: new Date().toISOString(),
    standard: 'WIA-AI-017'
};

console.log('Authentication Manifest:', JSON.stringify(manifest, null, 2));
            

ECDSA (Elliptic Curve Digital Signature Algorithm)

ECDSA with P-256 or P-384 curves provides flexibility and wide compatibility:

// Example: ECDSA Signing
const { privateKey, publicKey } = generateKeyPairSync('ec', {
    namedCurve: 'P-256',
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});

const signature = sign('sha256', contentHash, {
    key: privateKey,
    dsaEncoding: 'ieee-p1363'
});
            

RSA-PSS (RSA Probabilistic Signature Scheme)

RSA-PSS is recommended when compatibility with legacy systems is required:

Hash Functions

Cryptographic hash functions convert content of any size into fixed-size digests. For content authentication, hash functions must be:

SHA-256 and SHA-3

WIA-AI-017 mandates SHA-256 or SHA-3 for content hashing:

Algorithm Output Size Security Speed
SHA-256 256 bits 128-bit Fast (hardware acceleration)
SHA-3-256 256 bits 128-bit Moderate
SHA-512 512 bits 256-bit Fast on 64-bit systems
// Example: Multi-algorithm Hashing
import { createHash } from 'crypto';

function computeContentHash(content, algorithm = 'sha256') {
    const hash = createHash(algorithm);
    hash.update(content);
    return {
        algorithm: algorithm,
        hash: hash.digest('hex'),
        length: hash.digest().length * 8
    };
}

// Generate multiple hashes for redundancy
const hashes = {
    primary: computeContentHash(content, 'sha256'),
    secondary: computeContentHash(content, 'sha3-256'),
    fallback: computeContentHash(content, 'sha512')
};
            

Signature Verification

Verification is the inverse of signing. The verifier uses the signer's public key to confirm the signature is valid for the content.

// Example: Complete Verification Flow
import { verify, createHash } from 'crypto';

function verifyContentAuthenticity(content, manifest) {
    // Step 1: Compute content hash
    const computedHash = createHash('sha256')
        .update(content)
        .digest('hex');

    // Step 2: Check hash matches manifest
    if (computedHash !== manifest.content_hash) {
        return {
            valid: false,
            reason: 'Content has been modified',
            hash_match: false
        };
    }

    // Step 3: Verify signature
    try {
        const isValid = verify(
            null,
            Buffer.from(manifest.content_hash, 'hex'),
            {
                key: manifest.signer_public_key,
                format: 'pem'
            },
            Buffer.from(manifest.signature, 'base64')
        );

        return {
            valid: isValid,
            reason: isValid ? 'Signature valid' : 'Invalid signature',
            hash_match: true,
            signer: extractSignerInfo(manifest.signer_public_key),
            timestamp: manifest.timestamp
        };
    } catch (error) {
        return {
            valid: false,
            reason: 'Verification error: ' + error.message,
            hash_match: true
        };
    }
}

// Usage
const verificationResult = verifyContentAuthenticity(content, manifest);
console.log('Verification Result:', verificationResult);
            
⚠️ Common Verification Pitfalls

Certificate Management

X.509 certificates bind public keys to identities. In content authentication, certificates prove who signed the content.

Certificate Structure

An X.509 certificate contains:

// Example: Certificate Validation
import { X509Certificate } from 'crypto';

function validateCertificate(certPEM) {
    const cert = new X509Certificate(certPEM);

    // Check validity period
    const now = new Date();
    const notBefore = new Date(cert.validFrom);
    const notAfter = new Date(cert.validTo);

    if (now < notBefore || now > notAfter) {
        throw new Error('Certificate expired or not yet valid');
    }

    // Check key usage
    const keyUsage = cert.keyUsage;
    if (!keyUsage.includes('digitalSignature')) {
        throw new Error('Certificate not authorized for digital signatures');
    }

    // Verify certificate chain
    const issuerCert = loadIssuerCertificate(cert.issuer);
    if (!cert.verify(issuerCert.publicKey)) {
        throw new Error('Certificate signature invalid');
    }

    // Check revocation
    if (isCertificateRevoked(cert.serialNumber)) {
        throw new Error('Certificate has been revoked');
    }

    return {
        valid: true,
        subject: cert.subject,
        issuer: cert.issuer,
        validFrom: cert.validFrom,
        validTo: cert.validTo
    };
}
            

Timestamping

RFC 3161 timestamps prove when content was signed, preventing backdating attacks and establishing signature creation time.

Timestamp Authority (TSA)

A TSA is a trusted third party that:

  1. Receives a hash of the signature
  2. Adds a trusted timestamp
  3. Signs the timestamp with its private key
  4. Returns the timestamp token
// Example: Requesting Timestamp Token
async function getTimestamp(signature) {
    const signatureHash = createHash('sha256')
        .update(signature)
        .digest();

    // Create timestamp request
    const tsRequest = {
        version: 1,
        messageImprint: {
            hashAlgorithm: 'sha256',
            hashedMessage: signatureHash
        },
        certReq: true,
        nonce: generateNonce()
    };

    // Send to TSA
    const response = await fetch('https://tsa.example.com/timestamp', {
        method: 'POST',
        headers: { 'Content-Type': 'application/timestamp-query' },
        body: encodeTSRequest(tsRequest)
    });

    const tsToken = await response.arrayBuffer();

    // Verify timestamp token
    const timestamp = parseTimestampToken(tsToken);
    return {
        timestamp: timestamp.genTime,
        tsa: timestamp.tsa,
        serial: timestamp.serialNumber
    };
}
            

Hardware Security Modules (HSMs)

Private keys must be protected from theft or misuse. Hardware Security Modules provide tamper-resistant key storage and signing operations.

HSM Benefits

ℹ️ Cloud HSM Options
Major cloud providers offer HSM services:

Signature Formats

WIA-AI-017 supports multiple signature container formats:

CMS (Cryptographic Message Syntax)

CMS is the standard format for signed data, defined in RFC 5652. It supports:

JWS (JSON Web Signature)

JWS provides a JSON-based signature format, ideal for web applications:

// Example: Creating JWS
import { createSign } from 'crypto';

function createJWS(payload, privateKey) {
    // Header
    const header = {
        alg: 'EdDSA',
        typ: 'WIA-AUTH',
        kid: computeKeyId(publicKey)
    };

    // Encode header and payload
    const encodedHeader = base64url(JSON.stringify(header));
    const encodedPayload = base64url(JSON.stringify(payload));

    // Sign
    const signingInput = `${encodedHeader}.${encodedPayload}`;
    const signature = sign(null, Buffer.from(signingInput), privateKey);
    const encodedSignature = base64url(signature);

    // Return compact serialization
    return `${signingInput}.${encodedSignature}`;
}

// Usage
const jws = createJWS({
    content_hash: contentHash,
    timestamp: new Date().toISOString(),
    standard: 'WIA-AI-017'
}, privateKey);
            

Quantum-Resistant Cryptography

Current signature algorithms (Ed25519, ECDSA, RSA) are vulnerable to quantum computers. WIA-AI-017 provides migration guidance for post-quantum cryptography.

NIST Post-Quantum Standards

Recommended quantum-resistant algorithms:

⚠️ Quantum Timeline
While large-scale quantum computers may be decades away, content signed today could be stored and decrypted in the future. Consider hybrid signatures combining classical and post-quantum algorithms for long-term authentication.

Implementation Best Practices

Secure signature implementation requires attention to multiple details:

Key Management

  1. Generation: Use cryptographically secure random number generators
  2. Storage: Encrypt private keys at rest
  3. Access: Implement role-based access control
  4. Rotation: Regularly rotate signing keys
  5. Backup: Securely backup keys with split-knowledge

Signature Creation

Verification

✅ Security Checklist

📌 Key Takeaways

📝 Review Questions

  1. Explain the difference between symmetric and asymmetric cryptography in content authentication.
  2. Why is Ed25519 preferred over RSA for modern content authentication systems?
  3. What information does an X.509 certificate contain and why is each field important?
  4. Describe the complete flow of verifying a digitally signed image.
  5. Why must content be hashed before signing rather than signing the raw content?
  6. What role do Certificate Authorities play in the trust model?
  7. How do RFC 3161 timestamps prevent backdating attacks?
  8. Why are Hardware Security Modules important for high-value content authentication?
  9. What is the quantum computing threat to current signature algorithms?
  10. Describe three critical best practices for secure key management.

弘益人間 (홍익인간) · Benefit All Humanity