05Auth
Cryptography
Cryptography — Instruction 05
Coverage
CWE-327, CWE-330, CWE-338, CWE-347 OWASP A02:2021, ASVS V6
Algorithm Checks
1. Deprecated Algorithms — Never Use
// 🔴 CRITICAL — Broken/weak algorithms
MD5 // collision attacks trivial
SHA-1 // collision attacks known
DES // 56-bit key, brute-forceable
3DES // deprecated, Sweet32 attack
RC4 // stream cipher, broken
ECB mode // patterns visible in ciphertext
// 🟢 CORRECT — 2026 standard
AES-256-GCM // symmetric encryption
AES-256-CBC + HMAC-SHA256 // if GCM not possible
SHA-256 / SHA-384 / SHA-512 // hashing
RSA-2048+ / ECDSA P-256+ // asymmetric
Scan for:
crypto.createHash('md5') // 🔴
crypto.createHash('sha1') // 🔴
crypto.createCipheriv('des') // 🔴
crypto.createCipheriv('aes-256-ecb') // 🔴
2. Weak Random for Security
// 🔴 Math.random() is NOT cryptographically secure
const token = Math.random().toString(36) // predictable
const otp = Math.floor(Math.random() * 1000000) // predictable
// 🟢 Use crypto.randomBytes() always for security-sensitive values
const token = crypto.randomBytes(32).toString('hex')
const otp = crypto.randomInt(100000, 999999)
3. IV (Initialization Vector) Randomness
// 🔴 Static/hardcoded IV
const iv = Buffer.from('0000000000000000', 'hex') // NEVER
const iv = Buffer.alloc(16, 0) // NEVER
// 🟢 Random IV per encryption, stored with ciphertext
const iv = crypto.randomBytes(16)
const ciphertext = encrypt(data, key, iv)
const stored = iv.toString('hex') + ':' + ciphertext
4. Timing-Safe Comparison
// 🔴 Timing attack possible
if (token === req.headers['x-webhook-signature']) { }
if (hash1 === hash2) { }
// 🟢 Always use timingSafeEqual
import { timingSafeEqual } from 'crypto'
const safe = timingSafeEqual(Buffer.from(token), Buffer.from(expected))
Perfect Forward Secrecy (PFS)
5. TLS Ciphers with PFS
# Nginx — Force ECDHE/DHE (provides PFS)
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
# 🔴 Avoid: RSA key exchange (no PFS)
# 🟢 Prefer: ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)
Cryptographic Agility
6. Algorithm Configurable (not hardcoded everywhere)
// 🔴 Algorithm hardcoded in every function
function encrypt(data) {
return crypto.createCipheriv('aes-256-gcm', KEY, IV)
}
// 🟢 Centralized crypto module
// cryptoConfig.js
export const CIPHER_ALGO = process.env.CIPHER_ALGO || 'aes-256-gcm'
export const HASH_ALGO = process.env.HASH_ALGO || 'sha256'
export const KDF_ALGO = process.env.KDF_ALGO || 'argon2id'
Memory Safety (ASVS Level 3)
7. Zero Sensitive Data After Use
// 🔴 Secret stays in heap memory until GC
const privateKey = process.env.PRIVATE_KEY
signJWT(privateKey)
// privateKey accessible via memory dump
// 🟢 Use Buffer and zero after use
const keyBuf = Buffer.from(process.env.PRIVATE_KEY, 'utf8')
signJWT(keyBuf)
keyBuf.fill(0) // zeroes the memory immediately
// Python
import ctypes, sys
def zero_memory(s):
ctypes.memset(id(s), 0, sys.getsizeof(s))
8. Node.js Buffer Safety
// 🔴 Exposes uninitialized heap memory
Buffer(userInput) // deprecated + dangerous
Buffer.allocUnsafe(userInput) // uninitialized memory
new Buffer(100) // deprecated
// 🟢 Always initialized
Buffer.alloc(100) // zeroed
Buffer.from(string, 'utf8') // from known data
// 🔴 User-controlled size without limit
const buf = Buffer.alloc(req.body.size) // OOM if size=999999999
// 🟢 Validate size before allocation
const MAX_SIZE = 10 * 1024 * 1024 // 10MB
if (req.body.size > MAX_SIZE) return res.status(400)
const buf = Buffer.alloc(req.body.size)
Key Derivation
9. PBKDF2 / Argon2 for Password Hashing
// 🔴 Raw hash — not suitable for passwords
sha256(password)
// 🟢 Key derivation functions with salt and iterations
bcrypt.hash(password, 12) // cost=12 minimum
argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 2 ** 16, // 64 MB
timeCost: 3,
parallelism: 1
})
Certificate Pinning (ASVS Level 3)
10. API Client Certificate Validation
// For mobile clients / server-to-server calls
const agent = new https.Agent({
ca: fs.readFileSync('ca-cert.pem'),
checkServerIdentity: (host, cert) => {
// Verify fingerprint matches expected
const expected = process.env.API_CERT_FINGERPRINT
if (cert.fingerprint256 !== expected) {
throw new Error('Certificate mismatch')
}
}
})
Anti-Tampering (ASVS Level 3)
11. Code Integrity Verification
// Verify critical files haven't been modified at startup
import { createHash } from 'crypto'
import { readFileSync } from 'fs'
const EXPECTED_HASHES = {
'middleware/auth.js': process.env.AUTH_MIDDLEWARE_HASH
}
for (const [file, expectedHash] of Object.entries(EXPECTED_HASHES)) {
const actual = createHash('sha256').update(readFileSync(file)).digest('hex')
if (actual !== expectedHash) {
logger.error(`TAMPERING DETECTED: ${file}`)
process.exit(1)
}
}