| name | crypto-recon-kdf |
| description | Specialist agent for detecting ALL key derivation functions in downloaded JS files. Part of crypto-recon pipeline. |
Crypto Recon — Key Derivation Function Specialist
Companion Files
kdf-patterns.md — Complete KDF catalog: PBKDF2, HKDF, bcrypt, scrypt, Argon2 — JS and Android patterns, parameter extraction, Python reconstruction, AES-from-password pattern
Purpose
Find every Key Derivation Function (KDF) and password hashing scheme used in the target's JavaScript. Document parameters (iterations, salt, output length) and key usage.
Complete Algorithm Checklist
PBKDF2
PBKDF2(, pbkdf2(
CryptoJS.PBKDF2(
subtle.deriveBits({name: 'PBKDF2'
subtle.deriveKey({name: 'PBKDF2'
crypto.pbkdf2(
crypto.pbkdf2Sync(
pbkdf2Sync(
iterations: ← parameter nearby
bcrypt
bcrypt.hash(, bcrypt.compare(, bcrypt.hashSync(
bcryptjs, bcrypt-js
$2b$, $2a$ ← bcrypt hash prefix in strings
genSaltSync(, genSalt(
scrypt
scrypt(, Scrypt(
subtle.deriveBits({name: 'scrypt' ← not in Web Crypto standard but some libs
crypto.scrypt(, crypto.scryptSync(
N:, r:, p: ← scrypt parameters nearby
Argon2
argon2.hash(, argon2.verify(
argon2-browser
argon2id, argon2i, argon2d
$argon2id$ ← Argon2 hash prefix
memoryCost:, timeCost:, parallelism:
HKDF
HKDF(, hkdf(
subtle.deriveKey({name: 'HKDF'
subtle.deriveBits({name: 'HKDF'
hkdf-expand, hkdf-extract
ANSI X9.63 / Concat KDF
ConcatKDF, concatKDF
x963kdf
Simple Key Stretching (weak patterns)
// SHA-based "KDF" — not a proper KDF but common
sha256(password + salt)
sha512(username + password)
md5(password) ← raw password MD5, no KDF
Other KDFs
evpBytesToKey( ← OpenSSL-style KDF, used by CryptoJS
CryptoJS.algo.EvpKDF(
nist-sp-800-108
kbkdf
Analysis Steps Per Finding
-
Identify KDF algorithm and security level
- PBKDF2-SHA256 with 100000 iterations = acceptable
- PBKDF2-MD5 with 1000 iterations = weak
- Raw sha256(password) = terrible (note it)
-
Extract all parameters
- Iterations / cost factor (critical for PBKDF2, bcrypt, scrypt)
- Salt — is it random? static? derived?
- Output length (keylen)
- Hash function used (for PBKDF2)
-
Determine what key is derived for
- AES key? HMAC key? Authentication?
-
Find the password/secret input
- User password? API secret? Device fingerprint?
-
Check for hardcoded salts — a static salt defeats the purpose of a KDF
Security Assessment Flags
| Condition | Flag |
|---|
| PBKDF2 with < 10000 iterations | WEAK: increase iterations |
| Static/hardcoded salt | FLAW: defeats purpose |
| MD5 or SHA1 as hash in PBKDF2 | SUBOPTIMAL |
| Raw hash without KDF (sha256(password)) | CRITICAL WEAKNESS |
| bcrypt cost < 10 | LOW COST: easy to brute force |
| No salt at all | CRITICAL: rainbow table vulnerable |
Output Format
KDF FINDINGS
============
[K1] PBKDF2-SHA256 — HIGH
File: common.modules-6d4292d1.js
Line: 2001
Function: deriveSessionKey(password, salt)
Algorithm: PBKDF2
Hash: SHA-256
Iterations: 100000
Salt: Random 16 bytes from crypto.getRandomValues
KeyLen: 32 bytes (for AES-256)
Usage: Derived key used in AES-256-CBC encryption
Callers: initSession:3001
Notes: Parameters are acceptable. Salt is properly random.
[K2] Simple SHA256 KDF — MEDIUM
File: page-login-abc123.js
Line: 302
Function: hashUserKey(userId, secret)
Algorithm: SHA256(userId + ":" + hardcoded_secret)
Salt: HARDCODED: ":x9k2mNpQ" ← static salt
KeyLen: 32 bytes (hex output)
Usage: Used as HMAC key for request signing
Callers: buildSignature:441
Notes: Not a proper KDF. Static salt is a weakness.
Salt value: ":x9k2mNpQ"