AgentStack
SKILL verified MIT Self-run

Perseus Crypto

skill-kaivyy-perseus-crypto · by kaivyy

Deep-dive cryptography and secrets analysis (JWT, hashing, encryption, key management)

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-kaivyy-perseus-crypto

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Perseus Crypto? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Perseus Crypto Specialist

Context & Authorization

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.


Multi-Language Support

| 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 |


Overview

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.

Engagement Mode Compatibility

| 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 |

Safety Gates (Required)

  1. Read deliverables/engagement_profile.md before any runtime validation.
  2. Default to PRODUCTION_SAFE if mode is unspecified.
  3. Enforce kill-switch thresholds from engagement profile.
  4. Never expose real secrets, keys, or live credentials in outputs.

Cryptographic Issues Covered

| 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 |

Execution Instructions

Step 0: Mode & Scope Alignment

  • Load mode/scope/limits from deliverables/engagement_profile.md.
  • Respect deliverables/verification_scope.md when present.
  • Keep production checks passive-first and evidence-based.

Phase 1: JWT Analysis (4 Parallel Agents)

  1. JWT Algorithm Analyst:
  • "Find all JWT verification code. Check for algorithm validation."

Language-Specific Patterns: ```javascript // Node.js - VULNERABLE jwt.verify(token, secret); // Accepts any algorithm

// Node.js - SAFE jwt.verify(token, secret, { algorithms: ['HS256'] }); `` ``go // 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 # Python - VULNERABLE jwt.decode(token, secret) # Accepts any algorithm

# Python - SAFE jwt.decode(token, secret, algorithms=['HS256']) `` ``php // PHP - VULNERABLE JWT::decode($token, $key); // Check library defaults

// PHP - SAFE JWT::decode($token, new Key($key, 'HS256')); `` `rust // Rust - SAFE (explicit by design) decode::(&token, &DecodingKey::from_secret(secret), &Validation::new(Algorithm::HS256)) ``

  1. JWT Secret Analyst:
  • "Find JWT signing secrets across languages."

Patterns: ```javascript // 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 `` ``go // VULNERABLE var jwtSecret = []byte("weak-secret")

// SAFE var jwtSecret = []byte(os.Getenv("JWTSECRET")) `` ``python # VULNERABLE SECRETKEY = "secret"

# SAFE SECRETKEY = os.environ.get("JWTSECRET") ```

  1. JWT Claims Analyst:
  • "Analyze JWT claim validation."

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 |

  1. JWT Key Management Analyst:
  • "Check RS256/ES256 key handling."

Issues:

  • Private key in repository
  • Key without rotation
  • Public key as HMAC secret (algorithm confusion)

Phase 2: Password Hashing Analysis (3 Parallel Agents)

  1. Hash Algorithm Analyst:
  • "Find all password hashing across languages."

Language-Specific Patterns: ```javascript // 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 // 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 # 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 // PHP - VULNERABLE md5($password); sha1($password); hash('sha256', $password);

// PHP - SAFE passwordhash($password, PASSWORDARGON2ID); passwordhash($password, PASSWORDBCRYPT, ['cost' => 12]); `` `rust // Rust - SAFE bcrypt::hash(password, bcrypt::DEFAULT_COST)?; argon2::hash_encoded(password.as_bytes(), &salt, &config)?; ` ``java // Java - VULNERABLE MessageDigest.getInstance("MD5").digest(password.getBytes());

// Java - SAFE BCrypt.hashpw(password, BCrypt.gensalt(12)); ```

  1. Hash Comparison Analyst:
  • "Check for timing-safe comparison."

Patterns: ```javascript // VULNERABLE - Timing attack if (storedHash === computedHash) { ... }

// SAFE crypto.timingSafeEqual(Buffer.from(storedHash), Buffer.from(computedHash)) `` ``go // VULNERABLE if storedHash == computedHash { ... }

// SAFE subtle.ConstantTimeCompare([]byte(storedHash), []byte(computedHash)) `` ``python # VULNERABLE if storedhash == computedhash: ...

# SAFE hmac.comparedigest(storedhash, computed_hash) ```

  1. Password Policy Analyst:
  • "Check password strength enforcement."

Phase 3: Encryption Analysis (4 Parallel Agents)

  1. Cipher Selection Analyst:
  • "Find all encryption operations."

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: ```javascript // Node.js - VULNERABLE crypto.createCipher('des', key); crypto.createCipheriv('aes-128-ecb', key, '');

// Node.js - SAFE crypto.createCipheriv('aes-256-gcm', key, iv); `` ``go // Go - VULNERABLE des.NewCipher(key) cipher.NewCBCEncrypter(block, iv) // Without HMAC

// Go - SAFE cipher.NewGCM(block) `` ``python # 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) ```

  1. IV/Nonce Analyst:
  • "Check IV/nonce generation."

Issues: ```javascript // 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); ```

  1. Key Derivation Analyst:
  • "Check key derivation from passwords."

Patterns: ```javascript // VULNERABLE - Direct use const key = Buffer.from(password);

// SAFE - PBKDF2 crypto.pbkdf2Sync(password, salt, 100000, 32, 'sha256');

// SAFE - scrypt crypto.scryptSync(password, salt, 32); ```

  1. Key Management Analyst:
  • "Find encryption key storage issues."

Phase 4: Random Number Analysis (2 Parallel Agents)

  1. PRNG Analyst:
  • "Find insecure random number generation."

Language-Specific: ```javascript // VULNERABLE Math.random()

// SAFE crypto.randomBytes(32) crypto.randomUUID() `` ``go // VULNERABLE math/rand.Int()

// SAFE crypto/rand.Read(buf) `` ``python # VULNERABLE random.random() random.randint()

# SAFE secrets.tokenbytes(32) secrets.tokenhex(32) secrets.tokenurlsafe(32) `` ``php // VULNERABLE rand() mtrand()

// SAFE randombytes(32) randomint(0, PHPINTMAX) `` `rust // Use rand crate with OsRng use rand::rngs::OsRng; let random: u64 = OsRng.gen(); ` ``java // VULNERABLE new Random().nextInt()

// SAFE new SecureRandom().nextInt() ```

  1. Token Generation Analyst:
  • "Check security token generation."

Phase 5: Secrets in Code (3 Parallel Agents)

  1. Hardcoded Secrets Scanner:
  • "Deep scan for hardcoded secrets."

Patterns: ``` # AWS AKIA[0-9A-Z]{16}

# GitHub ghp[a-zA-Z0-9]{36} githubpat[a-zA-Z0-9]{22}[a-zA-Z0-9]{59}

# Stripe sklive[a-zA-Z0-9]{24} rklive[a-zA-Z0-9]{24}

# Private Keys -----BEGIN (RSA|EC|OPENSSH|PGP) PRIVATE KEY-----

# Generic (password|secret|key|token|api_key)\s[:=]\s['\"][^'\"]+['\"] ```

  1. Secret Exposure Analyst:
  • "Check where secrets might leak."

Locations:

  • Log files
  • Error messages
  • API responses
  • Client-side code
  • Git history
  1. Environment Variable Analyst:
  • "Check .env file security."

Issues:

  • .env in repository
  • .env.example with real secrets
  • Missing .env in .gitignore

Output Requirements

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:

  1. Take valid RS256 token
  2. Change header to HS256
  3. Sign with public key as secret
  4. Server verifies with public key as HMAC secret

Remediation:

const decoded = jwt.verify(token, publicKey, {
  algorithms: ['RS256']
});

[CRYPTO-002] MD5 Password Hashing

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))

Password Hashing Status

| Language | Algorithm | Cost/Rounds | Status | |----------|-----------|-------------|--------| | Node.js | bcrypt | 10 | WARN (use 12+) | | Python | MD5 | N/A | CRITICAL | | Go | bcrypt | 14 | OK |

Encryption Status

| Usage | Cipher | Mode | Status | |-------|--------|------|--------| | File encryption | AES-256 | ECB | CRITICAL | | API encryption | AES-128 | GCM | WARN (use 256) |

Random Number Generation

| Usage | Method | Status | |-------|--------|--------| | Session tokens | Math.random() | CRITICAL | | Password reset | crypto.randomBytes() | OK |

Hardcoded Secrets Found

| Type | Location | Severity | |------|----------|----------| | AWS Access Key | config/aws.js:3 | Critical | | JWT Secret | auth/jwt.js:5 | Critical | | Database Password | .env.example:8 | High |

Recommendations

Immediate Actions

  1. Implement algorithm validation for JWT
  2. Migrate password hashing to Argon2id or bcrypt (cost 12+)
  3. Move all secrets to environment variables
  4. Replace Math.random() with crypto.randomBytes()

Hashing Migration Guide

// 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.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kaivyy](https://github.com/kaivyy)
- **Source:** [kaivyy/perseus](https://github.com/kaivyy/perseus)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.