Password Hashing

Secure password storage using cryptographic hashing algorithms

Radiator Server supports multiple password hashing algorithms for secure credential storage. When user passwords are loaded from backends (SQL, JSON files, etc.), Radiator automatically detects the hashing algorithm based on the password format prefix and uses the appropriate verification method during authentication.

How It Works

  1. Passwords stored in backends include a prefix that identifies the hashing algorithm: {argon2}, {crypt-sha256}, etc.
  2. When a backend loads user data, the password format is detected automatically
  3. During authentication, Radiator compares the provided plaintext password against the stored hash using the appropriate algorithm
  4. No configuration is needed - the algorithm is determined by the password prefix

Supported Algorithms

Radiator supports the following password hashing algorithms:

AlgorithmPrefixSecurity LevelUse Case
Argon2{argon2}High (Recommended)Modern applications, resistant to GPU/ASIC attacks
Crypt SHA-512{crypt-sha512}MediumLegacy systems, Linux/Unix compatibility
Crypt SHA-256{crypt-sha256}MediumLegacy systems, Linux/Unix compatibility
NT Hash{nthash}LowWindows compatibility (not recommended for new systems)
Plaintext(no prefix)NoneDevelopment/testing only (never use in production)

Argon2 is the recommended password hashing algorithm, offering strong resistance against brute-force attacks including GPU and ASIC-based cracking attempts. Radiator uses Argon2id variant which provides balanced protection against both side-channel and GPU attacks.

Format:

{argon2}$argon2id$v=19$m=16384,t=2,p=1$<salt>$<hash>

Parameters:

  • m=4096 (4 MiB), m=16384 (16 MiB), or m=32768 (32 MiB) - Memory cost in KiB (specified via -m 12/14/15 where 2^n KiB)
  • t=2 or t=3 - Time cost (number of iterations through memory)
  • p=1 or p=2 - Parallelism (number of parallel threads)
  • Salt and hash are base64-encoded

Recommended settings:

  • Standard: t=2, p=1, m=4096 (4 MiB) - Good balance for most use cases
  • High security: t=2, p=1, m=16384 (16 MiB) - Better protection against attacks
  • Very high security: t=3, p=1, m=16384 (16 MiB) - Excellent protection

See "Performance Considerations" section below for detailed timing benchmarks.

Generate Argon2 hash:

# Standard security (4 MiB, ~100ms on typical vCPU)
echo -n "password" | argon2 $(openssl rand -base64 16) -id -t 2 -m 12 -p 1 -l 32 -e

# High security (16 MiB, ~400ms)
echo -n "password" | argon2 $(openssl rand -base64 16) -id -t 2 -m 14 -p 1 -l 32 -e

Example:

{argon2}$argon2id$v=19$m=16384,t=2,p=1$ZTM0ODY1YTUxZTQ1ZWFiNQ$MAz1wx2FHcKDw6vYVVUKTwR+Sc240NzMAQxjbtRhDbY

Crypt SHA-512

SHA-512 based crypt hashing, commonly used in Linux/Unix systems. Provides reasonable security for legacy applications.

Format:

{crypt-sha512}$6$rounds=5000$<salt>$<hash>

Example:

{crypt-sha512}$6$rounds=5000$saltsaltsal$hash...

Crypt SHA-256

SHA-256 based crypt hashing, similar to SHA-512 but with shorter hash length.

Format:

{crypt-sha256}$5$rounds=5000$<salt>$<hash>

Example:

{crypt-sha256}$5$rounds=5000$saltsaltsal$hash...

NT Hash

NT hash (MD4-based) used in Windows systems. Provided for compatibility but not recommended for new deployments due to weak security.

Format:

{nthash}<hex-encoded-hash>

Plaintext

Passwords without a prefix are treated as plaintext. This should only be used for development and testing.

Example:

mypassword123

Warning: Never use plaintext passwords in production environments.

Warning: If a plaintext password contains text that looks like a hash prefix (e.g., {argon2}, {crypt-sha256}), Radiator will attempt to parse it as a hashed password, causing authentication to fail. Always use hashed passwords to avoid this ambiguity.

Usage Examples

JSON File Backend

{
  "users": [
    {
      "username": "alice",
      "password": "{argon2}$argon2id$v=19$m=16384,t=2,p=1$..."
    },
    {
      "username": "bob",
      "password": "{crypt-sha512}$6$rounds=5000$..."
    }
  ]
}

SQL Backend

CREATE TABLE users (
    username VARCHAR(255) PRIMARY KEY,
    password TEXT NOT NULL
);

INSERT INTO users (username, password) VALUES
    ('alice', '{argon2}$argon2id$v=19$m=16384,t=2,p=1$...'),
    ('bob', '{crypt-sha256}$5$rounds=5000$...');

Backend Configuration

No special configuration is needed. The password format is detected automatically:

backends {
    sqlite "USERS" {
        filename "users.db";
        query "FIND_USER" {
            statement "SELECT username, password FROM users WHERE username = ?";
            bindings { aaa.identity; }
            mapping {
                user.username = username;
                user.password = password;  # Format auto-detected from prefix
            }
        }
    }
}

Security Recommendations

  1. Use Argon2 for new applications: Argon2id provides the best security against modern attack vectors
  2. Choose appropriate parameters: Use t=2, p=1, m=4096 (4 MiB) for standard security (~100ms), or m=16384 (16 MiB) for high security (~300-400ms)
  3. Generate unique salts: Always use cryptographically random salts (use openssl rand or equivalent)
  4. Migrate legacy hashes: If using crypt-sha256/512, consider migrating to Argon2
  5. Never use plaintext: Always hash passwords, even for development databases
  6. Avoid NT Hash: Only use for Windows integration where absolutely required

Performance Considerations

Password hashing is intentionally slow to prevent brute-force attacks. Performance characteristics on typical server vCPU:

  • Argon2 (t=2, p=1, m=4096): ~100ms per hash verification - recommended for most use cases
  • Argon2 (t=2, p=1, m=16384): ~300-400ms per hash verification - high security
  • Argon2 (t=3, p=1, m=16384): ~500-600ms per hash verification - very high security
  • Crypt SHA-512: ~30ms per hash verification
  • Crypt SHA-256: ~100ms per hash verification
  • NT Hash: <1ms per hash verification (weak security)

Parameter explanations:

  • t (time cost): Number of iterations through memory - higher = slower but more secure
  • p (parallelism): Number of threads - allows faster hashing with multi-core, but doesn't significantly improve security
  • m (memory cost): Amount of RAM in KiB (specified as 2^n) - higher memory requirements make GPU/ASIC attacks more expensive

Memory usage scaling:

The memory cost parameter directly affects Radiator's memory usage. Each parallel authentication request will allocate the specified amount of memory. For example:

  • With m=4096 (4 MiB): 10 parallel requests = ~40 MB RAM
  • With m=16384 (16 MiB): 10 parallel requests = ~160 MB RAM

Choose memory parameters based on expected concurrent authentication load and available server memory.

For high-throughput authentication servers, consider:

  • Using Argon2 with t=2, p=1, m=4096 (4 MiB) for ~100ms verification time