Skip to content

CWE-321: Use of Hard-coded Cryptographic Key

Overview

Hard-coded cryptographic keys embedded in source code, configuration files, or binaries are exposed to anyone with access to the codebase, version control, compiled binaries, or backups. All encrypted data becomes vulnerable, and keys cannot be rotated without redeploying code.

OWASP Classification

A04:2025 - Cryptographic Failures

Risk

Critical: Hard-coded keys enable decryption of all protected data, cannot be rotated without code changes, are exposed in version control history, decompiled binaries, and backups, violate compliance (PCI-DSS, HIPAA), and provide no key separation between environments.

Remediation Steps

Core principle: Never embed cryptographic keys in application artifacts (source code, binaries, images, or client-accessible configuration); keys must be provided to the application at runtime from a dedicated key-management boundary and treated as replaceable secrets.

Locate the hard-coded cryptographic key in your code

  • Check scan results: Review the specific file path, line number, and variable name where the hard-coded key appears
  • Search for key patterns: Grep codebase for "const KEY =", "SECRET_KEY =", "private static final", "AES_KEY =", suspicious base64 strings (long alphanumeric literals)
  • Review configuration files: Check application.properties, config.json, .env files committed to version control for encryption keys
  • Inspect compiled artifacts: Examine Docker images, JAR files, binaries where keys may be embedded
  • Check version control history: Search git history for previously committed keys that may still exist in old commits

Use external key management (Primary Defense)

  • Store keys in environment variables: Load from os.environ.get('ENCRYPTION_KEY'), not string literals
  • Use cloud KMS: AWS KMS, Azure Key Vault, GCP Cloud KMS for key storage and encryption operations
  • Use HashiCorp Vault: Centralized secret management with access control and audit logging
  • Never commit keys to version control: Add to .gitignore, remove from git history if already committed
  • Remove from Docker images: Don't bake keys into container images - inject at runtime

Generate keys at deployment/runtime

  • Generate unique keys per installation: Create different keys for each environment, customer, tenant
  • Use secure random number generators: secrets.token_bytes() (Python), SecureRandom (Java), crypto.randomBytes() (Node.js)
  • Store generated keys securely: Save to KMS, vault, or encrypted configuration - not in code
  • Rotate keys regularly: Implement key rotation schedule (quarterly, annually), automated rotation where possible

Implement proper key separation and derivation

  • Different keys per environment: Separate keys for dev, staging, production
  • Different keys per customer/tenant: Multi-tenant applications need per-tenant keys
  • Separate encryption and signing keys: Don't reuse same key for different purposes
  • Use key hierarchies: Master key encrypts data keys (envelope encryption)
  • Derive user-specific keys: Use PBKDF2/Argon2 to derive keys from master + user ID

Monitor and audit key usage

  • Track key access and usage (log encryption/decryption operations with key metadata)
  • Alert on unauthorized key access attempts
  • Audit key rotation and ensure keys are rotated on schedule
  • Monitor for hard-coded keys in new code (use secret scanning in CI/CD)
  • Review key management practices regularly (quarterly security audits)

Test the key management fix thoroughly

  • Verify no hard-coded keys remain in code (grep, secret scanning tools)
  • Test application loads keys from external source (environment, KMS, vault)
  • Test encryption/decryption works with externally managed keys
  • Test key rotation process (re-encrypt data with new key)
  • Verify different environments use different keys
  • Re-scan with security scanner to confirm the issue is resolved

Dynamic Scan Guidance

For guidance on remediating this CWE when detected by dynamic (DAST) scanners:

Common Vulnerable Patterns

  • const KEY = "hardcoded-secret-key"
  • Keys in application.properties
  • AES keys as string literals
  • Encryption keys in source code
  • Secrets in Docker images

Additional Resources