一键导入
perseus-crypto
Deep-dive cryptography and secrets analysis (JWT, hashing, encryption, key management)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Deep-dive cryptography and secrets analysis (JWT, hashing, encryption, key management)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | perseus-crypto |
| description | Deep-dive cryptography and secrets analysis (JWT, hashing, encryption, key management) |
IMPORTANT: This skill performs cryptographic security analysis on the user's own codebase. This is defensive security testing to find crypto weaknesses before they lead to data breaches.
Authorization: The user owns this codebase and has explicitly requested this specialized analysis.
| Language | Libraries |
|---|---|
| JavaScript/TypeScript | jsonwebtoken, jose, bcrypt, crypto, node-forge |
| Go | golang.org/x/crypto, crypto/*, jwt-go, golang-jwt |
| PHP | openssl, password_hash, sodium, firebase/php-jwt |
| Python | PyJWT, cryptography, bcrypt, passlib, hashlib |
| Rust | jsonwebtoken, ring, rust-crypto, argon2, bcrypt |
| Java | jjwt, Bouncy Castle, Java Cryptography Architecture |
| Ruby | jwt, bcrypt, rbnacl, openssl |
| C# | System.IdentityModel.Tokens.Jwt, BCrypt.Net |
This specialist skill performs comprehensive cryptographic analysis including JWT security, hashing, encryption, and key management across all major languages.
When to Use: After /scan identifies JWT usage, password hashing, encryption, or secrets handling.
Goal: Ensure cryptographic implementations follow security best practices.
| Mode | Specialist Behavior |
|---|---|
PRODUCTION_SAFE | Configuration and implementation analysis, minimal runtime checks |
STAGING_ACTIVE | Controlled token/crypto validation with throttling |
LAB_FULL | Extensive verification of crypto edge cases in lab |
LAB_RED_TEAM | Adversarial misuse simulation on test identities and synthetic keys |
deliverables/engagement_profile.md before any runtime validation.PRODUCTION_SAFE if mode is unspecified.| Category | Issues | Impact |
|---|---|---|
| JWT | Algorithm confusion, weak secrets, missing validation | Auth bypass |
| Hashing | MD5/SHA1 for passwords, missing salt, weak iterations | Credential theft |
| Encryption | Weak ciphers, ECB mode, hardcoded keys | Data exposure |
| Random | Predictable RNG, weak seeds | Token prediction |
| Key Management | Hardcoded keys, insecure storage | Full compromise |
deliverables/engagement_profile.md.deliverables/verification_scope.md when present.JWT Algorithm Analyst:
Language-Specific Patterns:
// Node.js - VULNERABLE
jwt.verify(token, secret); // Accepts any algorithm
// Node.js - SAFE
jwt.verify(token, secret, { algorithms: ['HS256'] });
// Go - VULNERABLE
token, _ := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
return secret, nil // No algorithm check!
})
// Go - SAFE
token, _ := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected method: %v", t.Header["alg"])
}
return secret, nil
})
# Python - VULNERABLE
jwt.decode(token, secret) # Accepts any algorithm
# Python - SAFE
jwt.decode(token, secret, algorithms=['HS256'])
// PHP - VULNERABLE
JWT::decode($token, $key); // Check library defaults
// PHP - SAFE
JWT::decode($token, new Key($key, 'HS256'));
// Rust - SAFE (explicit by design)
decode::<Claims>(&token, &DecodingKey::from_secret(secret), &Validation::new(Algorithm::HS256))
JWT Secret Analyst:
Patterns:
// VULNERABLE - Weak secret
const secret = 'secret123';
const secret = 'password';
// VULNERABLE - Hardcoded
jwt.sign(payload, 'my-super-secret-key');
// SAFE - From environment, strong
const secret = process.env.JWT_SECRET; // Must be 32+ chars
// VULNERABLE
var jwtSecret = []byte("weak-secret")
// SAFE
var jwtSecret = []byte(os.Getenv("JWT_SECRET"))
# VULNERABLE
SECRET_KEY = "secret"
# SAFE
SECRET_KEY = os.environ.get("JWT_SECRET")
JWT Claims Analyst:
Required Validations:
| Claim | Purpose | Check |
|---|---|---|
| exp | Expiration | Token not expired |
| iat | Issued At | Not issued in future |
| nbf | Not Before | Token is active |
| iss | Issuer | Trusted issuer |
| aud | Audience | Intended recipient |
JWT Key Management Analyst:
Issues:
Hash Algorithm Analyst:
Language-Specific Patterns:
// Node.js - VULNERABLE
crypto.createHash('md5').update(password).digest('hex');
crypto.createHash('sha1').update(password).digest('hex');
crypto.createHash('sha256').update(password).digest('hex'); // No salt!
// Node.js - SAFE
await bcrypt.hash(password, 12);
await argon2.hash(password);
// Go - VULNERABLE
md5.Sum([]byte(password))
sha256.Sum256([]byte(password))
// Go - SAFE
bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32)
# Python - VULNERABLE
hashlib.md5(password.encode()).hexdigest()
hashlib.sha256(password.encode()).hexdigest()
# Python - SAFE
bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
from passlib.hash import argon2
argon2.hash(password)
// PHP - VULNERABLE
md5($password);
sha1($password);
hash('sha256', $password);
// PHP - SAFE
password_hash($password, PASSWORD_ARGON2ID);
password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// Rust - SAFE
bcrypt::hash(password, bcrypt::DEFAULT_COST)?;
argon2::hash_encoded(password.as_bytes(), &salt, &config)?;
// Java - VULNERABLE
MessageDigest.getInstance("MD5").digest(password.getBytes());
// Java - SAFE
BCrypt.hashpw(password, BCrypt.gensalt(12));
Hash Comparison Analyst:
Patterns:
// VULNERABLE - Timing attack
if (storedHash === computedHash) { ... }
// SAFE
crypto.timingSafeEqual(Buffer.from(storedHash), Buffer.from(computedHash))
// VULNERABLE
if storedHash == computedHash { ... }
// SAFE
subtle.ConstantTimeCompare([]byte(storedHash), []byte(computedHash))
# VULNERABLE
if stored_hash == computed_hash: ...
# SAFE
hmac.compare_digest(stored_hash, computed_hash)
Password Policy Analyst:
Cipher Selection Analyst:
Vulnerable Ciphers:
| Cipher | Status | Use Instead |
|---|---|---|
| DES | Broken | AES-256-GCM |
| 3DES | Deprecated | AES-256-GCM |
| RC4 | Broken | AES-256-GCM |
| Blowfish | Weak | AES-256-GCM |
| AES-ECB | Insecure | AES-256-GCM |
| AES-CBC | OK (with HMAC) | AES-256-GCM preferred |
Language Patterns:
// Node.js - VULNERABLE
crypto.createCipher('des', key);
crypto.createCipheriv('aes-128-ecb', key, '');
// Node.js - SAFE
crypto.createCipheriv('aes-256-gcm', key, iv);
// Go - VULNERABLE
des.NewCipher(key)
cipher.NewCBCEncrypter(block, iv) // Without HMAC
// Go - SAFE
cipher.NewGCM(block)
# Python - VULNERABLE
from Crypto.Cipher import DES
cipher = AES.new(key, AES.MODE_ECB)
# Python - SAFE
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
IV/Nonce Analyst:
Issues:
// VULNERABLE - Static IV
const iv = Buffer.from('0000000000000000', 'hex');
// VULNERABLE - Predictable
const iv = Buffer.from(Date.now().toString());
// SAFE - Random
const iv = crypto.randomBytes(16);
Key Derivation Analyst:
Patterns:
// VULNERABLE - Direct use
const key = Buffer.from(password);
// SAFE - PBKDF2
crypto.pbkdf2Sync(password, salt, 100000, 32, 'sha256');
// SAFE - scrypt
crypto.scryptSync(password, salt, 32);
Key Management Analyst:
PRNG Analyst:
Language-Specific:
// VULNERABLE
Math.random()
// SAFE
crypto.randomBytes(32)
crypto.randomUUID()
// VULNERABLE
math/rand.Int()
// SAFE
crypto/rand.Read(buf)
# VULNERABLE
random.random()
random.randint()
# SAFE
secrets.token_bytes(32)
secrets.token_hex(32)
secrets.token_urlsafe(32)
// VULNERABLE
rand()
mt_rand()
// SAFE
random_bytes(32)
random_int(0, PHP_INT_MAX)
// Use rand crate with OsRng
use rand::rngs::OsRng;
let random: u64 = OsRng.gen();
// VULNERABLE
new Random().nextInt()
// SAFE
new SecureRandom().nextInt()
Token Generation Analyst:
Hardcoded Secrets Scanner:
Patterns:
# AWS
AKIA[0-9A-Z]{16}
# GitHub
ghp_[a-zA-Z0-9]{36}
github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}
# Stripe
sk_live_[a-zA-Z0-9]{24}
rk_live_[a-zA-Z0-9]{24}
# Private Keys
-----BEGIN (RSA|EC|OPENSSH|PGP) PRIVATE KEY-----
# Generic
(password|secret|key|token|api_key)\s*[:=]\s*['\"][^'\"]+['\"]
Secret Exposure Analyst:
Locations:
Environment Variable Analyst:
Issues:
Create deliverables/crypto_security_analysis.md:
# Cryptographic Security Analysis
## Summary
| Category | Issues | Critical | High | Medium |
|----------|--------|----------|------|--------|
| JWT | X | Y | Z | W |
| Hashing | X | Y | Z | W |
| Encryption | X | Y | Z | W |
| Random | X | Y | Z | W |
| Secrets | X | Y | Z | W |
## Language/Framework Detected
- Primary: [e.g., Node.js, Go, Python]
- Crypto Libraries: [e.g., crypto, bcrypt, jose]
## JWT Security Status
| Check | Status | Details |
|-------|--------|---------|
| Algorithm Validation | FAIL | Accepts 'none' algorithm |
| Secret Strength | FAIL | 8 character secret |
| Expiration | PASS | 1 hour expiry enforced |
| Issuer Validation | WARN | Not validated |
## Critical Findings
### [CRYPTO-001] JWT Algorithm Confusion
**Severity:** Critical
**Language:** Node.js
**Location:** `middleware/auth.js:23`
**Vulnerable Code:**
```javascript
const decoded = jwt.verify(token, publicKey);
Attack:
Remediation:
const decoded = jwt.verify(token, publicKey, {
algorithms: ['RS256']
});
Severity: Critical
Language: Python
Location: models/user.py:45
Vulnerable Code:
hashed = hashlib.md5(password.encode()).hexdigest()
Remediation:
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
| Language | Algorithm | Cost/Rounds | Status |
|---|---|---|---|
| Node.js | bcrypt | 10 | WARN (use 12+) |
| Python | MD5 | N/A | CRITICAL |
| Go | bcrypt | 14 | OK |
| Usage | Cipher | Mode | Status |
|---|---|---|---|
| File encryption | AES-256 | ECB | CRITICAL |
| API encryption | AES-128 | GCM | WARN (use 256) |
| Usage | Method | Status |
|---|---|---|
| Session tokens | Math.random() | CRITICAL |
| Password reset | crypto.randomBytes() | OK |
| Type | Location | Severity |
|---|---|---|
| AWS Access Key | config/aws.js:3 | Critical |
| JWT Secret | auth/jwt.js:5 | Critical |
| Database Password | .env.example:8 | High |
// Before
const hash = md5(password);
// After
const hash = await bcrypt.hash(password, 12);
// Or with Argon2
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536,
timeCost: 3,
parallelism: 4
});
**Next Step:** JWT vulnerabilities can be verified with crafted tokens.
Use when you want to run a full, automated penetration test from start to finish (Scan -> Audit -> Exploit -> Report)
Use when starting a security conversation to understand the Perseus methodology
Use when analyzing components for vulnerabilities (Phase 2 - Parallel Analysis)
Use when verifying vulnerabilities with Dynamic Exploit Generation (Phase 3)
Use when generating the final executive security report (Phase 4)
Run all specialist deep-dive skills in parallel for comprehensive analysis