Lesson 06 Secrets Management & Cryptographic Hygiene
Theme:

Secrets Management & Cryptographic Hygiene

Educational Use Only: The secrets scanning and cryptographic analysis techniques in this lesson are intended for authorized security auditing, blue team defense, and CTF competitions. Never exploit discovered credentials without explicit written authorization.

Why Secrets Management Matters

Leaked secrets are consistently the leading cause of preventable data breaches. According to the Verizon Data Breach Investigations Report, over 70% of breaches involve compromised credentials. The IBM Cost of a Data Breach report puts the average cost of a credentials-related breach above $4.5 million. These are not abstract statistics — they represent real organizations that suffered real damage because a secret ended up where it should not have been.

Consider some high-profile examples. In 2019, Capital One suffered a breach affecting over 100 million customers after a misconfigured WAF exposed AWS credentials that allowed an attacker to access S3 buckets. In 2022, Uber was breached when an attacker obtained a contractor's VPN credentials through social engineering, then found a PowerShell script on an internal network share containing hardcoded admin credentials for the company's Privileged Access Management system. Samsung leaked internal source code containing hardcoded credentials in a misconfigured GitLab instance, exposing secret keys for critical backend services. In every case, the root cause was the same: a secret existed somewhere it should not have, without adequate protection or rotation.

Automated bots scan GitHub for freshly pushed commits containing secrets within seconds of a push. Research has shown that a leaked AWS key on a public repository is typically exploited in under five minutes. The window between exposure and compromise is vanishingly small, which means prevention — not detection after the fact — is the only reliable strategy.

Secret Sprawl: Where Secrets Hide

Secret sprawl refers to the uncontrolled proliferation of credentials, API keys, tokens, and certificates across an organization's systems. Secrets tend to accumulate in places that developers do not think of as risky:

A critical .gitignore pattern for any project should include at minimum:

# .gitignore — secrets and sensitive files
.env
.env.*
*.pem
*.key
*.p12
*.pfx
credentials.json
service-account*.json
*secret*
!*secret*.example

Secret Detection Tools

Proactive scanning is essential for catching secrets before they reach production. Several tools specialize in this task:

TruffleHog scans git repositories, filesystem paths, and S3 buckets for high-entropy strings and known secret patterns. It understands git history and can scan every commit, not just the working tree:

# Scan a local repository including all git history
trufflehog git file://. --only-verified

# Scan a remote GitHub repository
trufflehog github --repo https://github.com/org/repo --only-verified

# Scan a filesystem path
trufflehog filesystem /path/to/project --only-verified

Gitleaks is a fast, SAST-oriented tool that integrates well with CI/CD pipelines. It uses regex patterns and entropy analysis to detect secrets:

# Scan a repository
gitleaks detect --source . --verbose

# Scan only staged changes (pre-commit hook)
gitleaks protect --staged --verbose

# Generate a report
gitleaks detect --source . --report-format json --report-path report.json

detect-secrets from Yelp takes a baseline approach. It creates a snapshot of known secrets and alerts only on new ones, reducing noise in legacy codebases:

# Create a baseline
detect-secrets scan > .secrets.baseline

# Audit the baseline interactively
detect-secrets audit .secrets.baseline

# Check for new secrets against the baseline
detect-secrets scan --baseline .secrets.baseline

git-secrets from AWS Labs installs as a git hook to prevent commits containing AWS credentials and other configurable patterns:

# Install hooks in a repository
git secrets --install

# Register AWS patterns
git secrets --register-aws

# Scan the repository
git secrets --scan

Secrets Management Solutions

Detection finds existing problems; a secrets management solution prevents them from occurring. The principle is simple: applications should never contain secrets directly. Instead, they retrieve secrets at runtime from a centralized, access-controlled vault.

HashiCorp Vault is the industry standard for secrets management. It provides dynamic secrets, encryption as a service, lease-based access with automatic revocation, and detailed audit logging:

# Store a secret
vault kv put secret/myapp/database username="dbadmin" password="s3cur3P@ss!"

# Retrieve a secret
vault kv get secret/myapp/database

# Retrieve just the password field
vault kv get -field=password secret/myapp/database

# Enable a dynamic database secrets engine
vault secrets enable database
vault write database/config/mydb \
    plugin_name=mysql-database-plugin \
    connection_url="{{username}}:{{password}}@tcp(db.example.com:3306)/" \
    allowed_roles="readonly" \
    username="vault_admin" \
    password="vault_password"

# Generate a short-lived database credential
vault read database/creds/readonly

AWS Secrets Manager integrates natively with AWS services, providing automatic rotation for RDS credentials and cross-account access. Azure Key Vault offers similar capabilities within the Azure ecosystem, with HSM-backed key storage and managed identity integration. For teams already invested in a cloud provider, the native solution often provides the smoothest integration path.

Cryptographic Hygiene: Choosing Algorithms and Key Sizes

Cryptographic hygiene means using modern, well-vetted algorithms with appropriate key sizes, and retiring deprecated cryptography before it becomes a vulnerability. The following table summarizes current recommendations:

PurposeRecommendedDeprecated / Avoid
Symmetric encryptionAES-256-GCM, ChaCha20-Poly1305DES, 3DES, RC4, AES-ECB mode
Asymmetric encryptionRSA-4096, ECDSA P-256/P-384, Ed25519RSA-1024, DSA
HashingSHA-256, SHA-384, SHA-512, SHA-3MD5, SHA-1
Key exchangeECDH (X25519), DH-4096DH-1024, static RSA key exchange
Password hashingArgon2id, bcrypt, PBKDF2MD5, SHA-1, unsalted hashes

A practical example using Python's cryptography library for AES-256-GCM encryption:

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# Generate a 256-bit key
key = AESGCM.generate_key(bit_length=256)

# Encrypt
aesgcm = AESGCM(key)
nonce = os.urandom(12)  # 96-bit nonce for GCM
plaintext = b"Sensitive data that must be protected"
associated_data = b"authenticated-but-not-encrypted-metadata"
ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)

# Decrypt
decrypted = aesgcm.decrypt(nonce, ciphertext, associated_data)
assert decrypted == plaintext

TLS Configuration Best Practices

Transport Layer Security is the backbone of secure communication, but misconfigured TLS is nearly as dangerous as no TLS at all. Key principles:

Example Nginx TLS configuration:

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers on;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # HSTS — 2 year max-age, include subdomains, preload
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
}

Certificate Management and Rotation

Certificates are secrets too, and they expire. Poor certificate management leads to outages (expired certs) and breaches (compromised private keys that are never rotated). Best practices include:

Password Hashing: bcrypt, Argon2, and PBKDF2

Storing passwords requires purpose-built hashing functions that are deliberately slow and memory-intensive to resist brute-force attacks. General-purpose hash functions like SHA-256 are far too fast — a modern GPU can compute billions of SHA-256 hashes per second.

Argon2id is the current gold standard, winner of the Password Hashing Competition. It is resistant to both GPU-based and side-channel attacks due to its configurable memory and parallelism parameters:

from argon2 import PasswordHasher

ph = PasswordHasher(
    time_cost=3,        # Number of iterations
    memory_cost=65536,  # 64 MB memory usage
    parallelism=4       # Number of parallel threads
)

# Hash a password
hashed = ph.hash("user_password_here")
# Example output: $argon2id$v=19$m=65536,t=3,p=4$...

# Verify a password
try:
    ph.verify(hashed, "user_password_here")
    print("Password is correct")
except Exception:
    print("Password is incorrect")

bcrypt remains widely supported and is a solid choice when Argon2 is not available. Its work factor (cost parameter) should be set so that hashing takes at least 250 milliseconds on your production hardware:

import bcrypt

password = b"user_password_here"
salt = bcrypt.gensalt(rounds=12)  # 2^12 iterations
hashed = bcrypt.hashpw(password, salt)

# Verify
if bcrypt.checkpw(password, hashed):
    print("Password is correct")

PBKDF2 is acceptable when regulatory compliance requires NIST-approved algorithms. Use at least 600,000 iterations with SHA-256 as of current OWASP guidance.

AI-Assisted Crypto Review

One of the most powerful applications of AI in blue team operations is using LLMs to audit cryptographic usage across a codebase. Manually reviewing every file for weak algorithms, hardcoded keys, insecure defaults, and deprecated patterns is time-consuming and error-prone. Claude can accelerate this process significantly:

import anthropic

client = anthropic.Anthropic()

# Example: submit a code snippet for crypto review
code_to_review = """
import hashlib
from Crypto.Cipher import DES

def encrypt_data(key, data):
    cipher = DES.new(key, DES.MODE_ECB)
    padded = data + b' ' * (8 - len(data) % 8)
    return cipher.encrypt(padded)

def hash_password(password):
    return hashlib.md5(password.encode()).hexdigest()
"""

message = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": (
                "You are a cryptographic security auditor. Review the following "
                "Python code for cryptographic weaknesses. For each issue found, "
                "explain the vulnerability, its severity, and provide a corrected "
                "implementation using modern, secure alternatives.\n\n"
                f"```python\n{code_to_review}\n```"
            )
        }
    ]
)

print(message.content[0].text)

Claude would identify multiple critical issues in this code: the use of DES (56-bit key, easily brute-forced), ECB mode (identical plaintext blocks produce identical ciphertext blocks, leaking patterns), space-based padding (non-standard, potentially exploitable), and MD5 for password hashing (no salt, extremely fast, trivially reversible with rainbow tables). It would recommend replacing DES-ECB with AES-256-GCM, using the cryptography library instead of the deprecated pycryptodome DES module, and switching from MD5 to Argon2id for password hashing.

You can extend this approach to scan entire codebases by walking directory trees, extracting files that import cryptographic modules, and feeding them to Claude for batch analysis. This is particularly valuable during security audits, code reviews, and compliance assessments.

Key Takeaways

Secrets management and cryptographic hygiene are foundational blue team disciplines. A single leaked credential or weak cipher can undo every other security control in your environment.

Self-check: Can you explain why ECB mode is insecure? Can you list three places where secrets commonly hide in a development workflow? Can you write a TruffleHog command to scan a repository's full git history? Can you describe the difference between Argon2id and bcrypt, and explain when you would choose one over the other?

Download Files

These files contain synthetic data for the secrets and crypto challenges. All files are plain text (.txt) and safe to open.