Skip to main content

Overview

OpenVPN requires various types of cryptographic keys and secrets for secure operation. This guide covers generating all types of keys using the --genkey command and other cryptographic tools.

The genkey command

The --genkey command generates cryptographic keys for OpenVPN in standalone mode.

Syntax

openvpn --genkey keytype keyfile
If keyfile is omitted or empty, the key will be output to stdout.

Available key types

Key TypeDescriptionUsage
secretStandard shared secret keyStatic key mode, tls-auth, tls-crypt
tls-authAlias for secretTLS authentication
tls-cryptAlias for secretTLS encryption and authentication
tls-crypt-v2-serverServer key for TLS crypt v2Large deployments with per-client keys
tls-crypt-v2-clientClient key for TLS crypt v2Generated per client
auth-tokenAuthentication token keyToken-based authentication

Shared secret keys

Shared secret keys are used for static key mode, --tls-auth, and --tls-crypt.

Generating shared secrets

# Generate a shared secret
openvpn --genkey secret shared.key

Key format

Shared secret keys are 2048 bits (256 bytes) and stored in PEM-like format:
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
e3b0c44298fc1c149afbf4c8996fb924
27ae41e4649b934ca495991b7852b855
...
-----END OpenVPN Static key V1-----

Distributing shared secrets

Shared secret keys must be distributed over a secure channel (e.g., SSH, encrypted email, physical media). Never transmit unencrypted over the network.
# Securely copy to remote host
scp shared.key user@remote-host:/etc/openvpn/

# Or use ssh to pipe directly
openvpn --genkey secret | ssh user@remote-host 'cat > /etc/openvpn/shared.key'

TLS authentication keys

Generating tls-auth keys

1

Generate the key

openvpn --genkey tls-auth ta.key
2

Configure server

# Server configuration
tls-auth ta.key 0
3

Configure clients

# Client configuration (note opposite direction)
tls-auth ta.key 1
4

Distribute key securely

# Copy to clients securely
scp ta.key user@client:/etc/openvpn/
The direction parameter (0 or 1) uses different parts of the 2048-bit key for send and receive operations, allowing bidirectional communication with different HMAC keys.

Generating tls-crypt keys

# Generate tls-crypt key
openvpn --genkey tls-crypt tc.key

# Both server and client use same configuration
# Server config:
tls-crypt tc.key

# Client config:
tls-crypt tc.key
Advantages:
  • No direction parameter needed
  • Control channel packets are encrypted
  • Provides privacy and post-quantum security

TLS crypt v2 keys

TLS crypt v2 provides client-specific keys for improved security in large deployments.

Generating tls-crypt-v2 server key

1

Generate server key

openvpn --genkey tls-crypt-v2-server v2server.key
This creates a 2048-bit key containing:
  • First 256 bits of key 1: AES-256-CTR encryption key
  • First 256 bits of key 2: HMAC-SHA-256 authentication key
2

Configure server

# Basic configuration
tls-crypt-v2 v2server.key

# Or force modern cookie-based handshake (OpenVPN 2.6+)
tls-crypt-v2 v2server.key force-cookie
3

Secure the key

chmod 600 v2server.key
chown root:root v2server.key

Generating tls-crypt-v2 client keys

Client keys are generated using the server key:
1

Generate client key with default metadata

openvpn --tls-crypt-v2 v2server.key --genkey tls-crypt-v2-client v2client-1.key
By default, OpenVPN uses a 64-bit Unix timestamp (key generation time) as metadata.
2

Generate client key with custom metadata

# Metadata must be base64-encoded, max 733 bytes (980 base64 characters)
# Example: encoding "user=john,serial=12345"
echo -n "user=john,serial=12345" | base64
# Output: dXNlcj1qb2huLHNlcmlhbD0xMjM0NQ==

openvpn --tls-crypt-v2 v2server.key --genkey tls-crypt-v2-client v2client-1.key "dXNlcj1qb2huLHNlcmlhbD0xMjM0NQ=="
3

Configure client

# Client configuration
tls-crypt-v2 v2client-1.key

Metadata types

The first byte of metadata determines its type:
TypeValueDescription
USER0x00User-defined free-form data
TIMESTAMP0x0164-bit network order Unix timestamp

Automated client key generation

#!/bin/bash
# Generate client keys for multiple users

SERVER_KEY="v2server.key"
OUTPUT_DIR="./client-keys"

mkdir -p $OUTPUT_DIR

for client in alice bob charlie; do
    # Generate metadata with username and timestamp
    metadata=$(echo -n "user=$client,created=$(date +%s)" | base64)
    
    # Generate client key
    openvpn --tls-crypt-v2 $SERVER_KEY \
        --genkey tls-crypt-v2-client \
        $OUTPUT_DIR/${client}.key \
        "$metadata"
    
    echo "Generated key for $client"
done

Verifying client metadata

# Server configuration with metadata verification
tls-crypt-v2-verify /etc/openvpn/verify-metadata.sh

# Set maximum age for client keys (365 days)
tls-crypt-v2-max-age 365
Example verification script:
#!/bin/bash
# /etc/openvpn/verify-metadata.sh

# Environment variables available:
# - script_type: "tls-crypt-v2-verify"
# - metadata_type: "0" (user) or "1" (timestamp)
# - metadata_file: path to file containing metadata

if [ "$metadata_type" = "0" ]; then
    # User-defined metadata
    metadata=$(cat "$metadata_file")
    # Parse and verify metadata
    # Exit 0 to accept, non-zero to reject
elif [ "$metadata_type" = "1" ]; then
    # Timestamp metadata (already checked by --tls-crypt-v2-max-age)
    exit 0
fi

exit 1

Authentication token keys

Authentication tokens allow clients to reconnect without re-authenticating.

Generating auth token keys

# Generate to file
openvpn --genkey auth-token auth-token.key

# Generate to stdout
openvpn --genkey auth-token

Using auth token keys

# Server configuration
auth-gen-token-secret auth-token.key
This file should be kept secret to the server. Anyone with access to this file can generate valid authentication tokens that the OpenVPN server will accept.

Hardware-accelerated key generation

Viewing available crypto engines

# Show hardware crypto acceleration engines
openvpn --show-engines

Using hardware acceleration

# Use specific engine for key generation
engine rdrand  # Use CPU's RDRAND instruction

Key file security

File permissions

# Private keys and secrets should be readable only by root
chmod 600 /etc/openvpn/*.key
chown root:root /etc/openvpn/*.key

# Certificates can be world-readable
chmod 644 /etc/openvpn/*.crt

Secure storage

1

Encrypt private keys

# Encrypt key file with password
openssl enc -aes-256-cbc -salt -in server.key -out server.key.enc

# Decrypt when needed
openssl enc -d -aes-256-cbc -in server.key.enc -out server.key
2

Use secure deletion

# Securely delete old keys
shred -vfz -n 10 old-key.key
3

Backup securely

# Create encrypted backup
tar czf - /etc/openvpn/*.key | openssl enc -aes-256-cbc -out openvpn-keys.tar.gz.enc

Key rotation

Rotating tls-auth/tls-crypt keys

1

Generate new key

openvpn --genkey tls-crypt tc-new.key
2

Configure dual keys temporarily

# Server supports both old and new keys during transition
tls-crypt tc-old.key
# Note: Full dual-key support requires configuration management
3

Update clients gradually

Distribute new key to clients and update their configurations.
4

Remove old key

Once all clients are updated, remove old key from server configuration.

Rotating tls-crypt-v2 keys

With tls-crypt-v2, each client has unique keys:
# Generate new server key
openvpn --genkey tls-crypt-v2-server v2server-new.key

# Generate new client keys
for client in client1 client2 client3; do
    openvpn --tls-crypt-v2 v2server-new.key \
        --genkey tls-crypt-v2-client ${client}-new.key
done

Key derivation and format

Static key format

Static keys use the following structure:
Struct key {
    uint8_t cipher[MAX_CIPHER_KEY_LENGTH];  // Cipher key material
    uint8_t hmac[MAX_HMAC_KEY_LENGTH];      // HMAC key material
};
For bidirectional keys:
Struct key2 {
    struct key keys[2];  // keys[0]: client->server, keys[1]: server->client
};

Key direction

DirectionEncrypt KeyDecrypt Key
Bidirectional (none)keys[0]keys[0]
Normal (0)keys[0]keys[1]
Inverse (1)keys[1]keys[0]

Best practices

  1. Use cryptographically secure random sources - OpenVPN uses the system’s random number generator
  2. Generate keys on secure systems - Generate keys on trusted, offline systems when possible
  3. Never reuse keys - Generate unique keys for each purpose and deployment
  4. Secure distribution - Always use secure channels (SSH, encrypted email, physical media)
  5. Regular rotation - Rotate shared keys periodically, especially tls-crypt in large deployments
  6. Use tls-crypt-v2 for scale - Large deployments should use per-client keys
  7. Set proper permissions - Restrict access to key files (mode 600)
  8. Backup securely - Encrypt backups of key material
  9. Document key usage - Maintain inventory of which keys are used where
  10. Monitor key age - Implement alerting for keys that need rotation

Troubleshooting

Insufficient entropy

# Check available entropy
cat /proc/sys/kernel/random/entropy_avail

# Install entropy daemon if needed
apt-get install haveged
systemctl enable haveged
systemctl start haveged

Key format errors

Error: “Cannot load inline file”
  • Check PEM format headers and footers
  • Ensure no extra whitespace or characters
  • Verify base64 encoding is valid
Error: “Bad key direction”
  • Ensure direction parameter matches between peers
  • Use 0 on one side, 1 on the other
  • Or omit direction on both sides

Verifying key integrity

# Check key file integrity
head -1 shared.key  # Should show "-----BEGIN OpenVPN Static key V1-----"
tail -1 shared.key  # Should show "-----END OpenVPN Static key V1-----"

# Count lines (should be consistent)
wc -l shared.key

Advanced key generation

Using custom random sources

# Use hardware random number generator
openvpn --genkey secret | cat /dev/hwrng > custom.key

Generating test keys

# Generate ephemeral keys for testing
openvpn --genkey secret /tmp/test.key

# Test configuration
openvpn --config test.conf --secret /tmp/test.key

# Clean up
shred -vfz -n 3 /tmp/test.key