Cryptographic hash functions are algorithms that take input data of any size and produce a fixed-size output value, called a hash or digest.

What is a Hash Function?

A cryptographic hash function is a mathematical algorithm that converts input data into a fixed-length character string, designed to be irreversible and collision-resistant.

Main Characteristics

Fundamental Properties

  • Deterministic: Same input = same output
  • Fixed size: Constant length output
  • Fast: Efficient calculation
  • Irreversible: Cannot obtain input from output

Cryptographic Properties

  • Preimage resistance: Hard to find input for given hash
  • Second preimage resistance: Hard to find second input with same hash
  • Collision resistance: Hard to find two inputs with same hash
  • Avalanche effect: Small change in input = large change in output

Main Algorithms

MD5 (Message Digest 5)

  • Size: 128 bits (16 bytes)
  • Status: Obsolete, not secure
  • Use: Only for non-critical checksums
  • Vulnerabilities: Known collisions

SHA-1 (Secure Hash Algorithm 1)

  • Size: 160 bits (20 bytes)
  • Status: Obsolete, not recommended
  • Use: Legacy systems only
  • Vulnerabilities: Theoretical collisions

SHA-2 Family

  • SHA-224: 224 bits (28 bytes)
  • SHA-256: 256 bits (32 bytes) ✅ Recommended
  • SHA-384: 384 bits (48 bytes)
  • SHA-512: 512 bits (64 bytes) ✅ Recommended

SHA-3 Family

  • SHA3-224: 224 bits (28 bytes)
  • SHA3-256: 256 bits (32 bytes) ✅ Recommended
  • SHA3-384: 384 bits (48 bytes)
  • SHA3-512: 512 bits (64 bytes) ✅ Recommended

BLAKE2

  • BLAKE2b: Up to 512 bits
  • BLAKE2s: Up to 256 bits
  • Status: Modern, efficient
  • Use: Alternative to SHA-3

Implementation

Python with hashlib

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import hashlib

# SHA-256
data = b"Hello, World!"
hash_sha256 = hashlib.sha256(data).hexdigest()
print(f"SHA-256: {hash_sha256}")

# SHA-512
hash_sha512 = hashlib.sha512(data).hexdigest()
print(f"SHA-512: {hash_sha512}")

# SHA-3
hash_sha3 = hashlib.sha3_256(data).hexdigest()
print(f"SHA3-256: {hash_sha3}")

# BLAKE2
hash_blake2 = hashlib.blake2b(data).hexdigest()
print(f"BLAKE2b: {hash_blake2}")

OpenSSL Command Line

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# SHA-256
echo -n "Hello, World!" | openssl dgst -sha256

# SHA-512
echo -n "Hello, World!" | openssl dgst -sha512

# SHA-3
echo -n "Hello, World!" | openssl dgst -sha3-256

# Verify file
openssl dgst -sha256 -verify public.key -signature signature.bin file.txt

JavaScript (Node.js)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const crypto = require('crypto');

// SHA-256
const hash = crypto.createHash('sha256');
hash.update('Hello, World!');
console.log('SHA-256:', hash.digest('hex'));

// SHA-512
const hash512 = crypto.createHash('sha512');
hash512.update('Hello, World!');
console.log('SHA-512:', hash512.digest('hex'));

Applications

Data Integrity

  • File verification: File checksums
  • Transmission: Verify integrity over network
  • Storage: Detect corruption
  • Backups: Verify backups

Authentication

  • Passwords: Store password hashes
  • Tokens: Generate unique tokens
  • Sessions: Identify sessions
  • API Keys: Generate API keys

Digital Signatures

  • Message hash: Summarize message before signing
  • Efficiency: Sign hash instead of full message
  • Integrity: Verify message hasn’t changed
  • Authenticity: Confirm message origin

Blockchain

  • Merkle Trees: Data structures
  • Proof of Work: Consensus algorithms
  • Block Hashing: Identify blocks
  • Transaction Hashing: Identify transactions

HMAC (Hash-based Message Authentication Code)

What is HMAC?

HMAC combines a hash function with a secret key to create a message authentication code.

Implementation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import hmac
import hashlib

# Create HMAC
key = b"secret-key"
message = b"Hello, World!"
hmac_sha256 = hmac.new(key, message, hashlib.sha256).hexdigest()

# Verify HMAC
def verify_hmac(key, message, received_hmac):
    expected_hmac = hmac.new(key, message, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected_hmac, received_hmac)

HMAC Applications

  • API Authentication: API authentication
  • JWT: JSON Web Tokens
  • Webhooks: Verify webhook origin
  • Session Management: Session management

Salt and Pepper

Salt

  • Definition: Random value added to input
  • Purpose: Prevent dictionary attacks
  • Use: Store with hash
  • Generation: Cryptographically secure

Pepper

  • Definition: Secret value added to input
  • Purpose: Add additional secret
  • Use: Not stored with hash
  • Storage: Separate and secure

Implementation with Salt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import hashlib

def hash_password(password, salt=None):
    if salt is None:
        salt = os.urandom(32)  # 256 bits
    
    # Combine password + salt
    salted_password = password.encode() + salt
    
    # Calculate hash
    hash_value = hashlib.sha256(salted_password).digest()
    
    return salt + hash_value

def verify_password(password, stored_hash):
    # Extract salt (first 32 bytes)
    salt = stored_hash[:32]
    
    # Calculate hash with salt
    calculated_hash = hash_password(password, salt)
    
    # Compare
    return calculated_hash == stored_hash

Attacks and Vulnerabilities

Attack Types

  • Brute Force: Try all possibilities
  • Dictionary Attack: Use common dictionaries
  • Rainbow Tables: Precalculated tables
  • Collision Attack: Find collisions

Protections

  • Salt: Prevent rainbow tables
  • Pepper: Add additional secret
  • Iterations: Multiple rounds (PBKDF2, bcrypt)
  • Strong algorithms: Use SHA-256 or higher

Best Practices

  • Algorithm: Use SHA-256 or SHA-3
  • Salt: Use unique salt per input
  • Iterations: Use PBKDF2 or bcrypt for passwords
  • Length: Salt of at least 128 bits

Algorithm Comparison

Performance

  • MD5: Faster (insecure)
  • SHA-1: Fast (insecure)
  • SHA-256: Moderate (secure)
  • SHA-512: Slower (more secure)
  • SHA-3: Slower (more secure)

Security

  • MD5: Insecure, collisions
  • SHA-1: Insecure, theoretical collisions
  • SHA-256: Secure, recommended
  • SHA-512: Very secure
  • SHA-3: Very secure, attack-resistant

Recommendations

  • General applications: SHA-256
  • High security: SHA-512 or SHA-3
  • Legacy systems: Migrate to SHA-256
  • New projects: SHA-3 or BLAKE2

Best Practices

Algorithm Selection

  • SHA-256: For most applications
  • SHA-512: For high security applications
  • SHA-3: For maximum security
  • BLAKE2: For high performance applications

Implementation

  • Proven libraries: Use standard implementations
  • Unique salt: Generate unique salt per input
  • Iterations: Use PBKDF2 or bcrypt for passwords
  • Verification: Implement secure verification

Management

  • Rotation: Rotate hashes regularly
  • Monitoring: Monitor attack attempts
  • Audit: Regular security audits
  • Update: Keep algorithms updated

References