Day 2 of my 21-day API challenge is done.
Yesterday I built an Invoice & Receipt Parser API. Today I built a Password Strength & Security Scorer API — a complete password security toolkit that any developer can drop into their signup flow in minutes.
If you missed Day 1, catch up here: https://dev.to/ruanmuller04
The Problem
Every app with a login form needs password validation. Most developers end up writing the same basic checks:
// The lazy version every dev writes at 2am
if (password.length < 8) return "too short";
if (!/[A-Z]/.test(password)) return "needs uppercase";
It works. But it misses so much — common breached passwords, keyboard patterns, crack time estimates, entropy calculations. Building all of that properly takes days.
So I built an API that does it properly in one call.
What I Built
The Password Strength & Security Scorer API — send it a password, get back a full security report.
Input:
{
"password": "password123"
}
Output:
{
"success": true,
"data": {
"score": 0,
"grade": "F",
"strength": "very weak",
"entropy_bits": 58.5,
"crack_time": {
"display": "5 months",
"online_attack": "58 years",
"offline_attack": "5 months"
},
"patterns": {
"is_common_password": true,
"has_sequential_nums": true,
"ends_with_number": true
},
"feedback": [
"This is one of the most common passwords",
"Contains sequential numbers (e.g. 123)",
"Ends with a number — very predictable"
],
"suggestions": [
"Choose a completely different password",
"Add uppercase letters (A-Z)",
"Add symbols (!@#$%^&*)"
]
}
}
And for a strong password:
{
"password": "K#9mP$vL2@nQ8xR!"
}
{
"score": 75,
"grade": "B",
"strength": "strong",
"crack_time": { "display": "2 million years" }
}
The 6 Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| POST | /analyze |
Full password analysis |
| POST | /analyze/batch |
Analyze up to 20 passwords at once |
| POST | /check/breach |
Check against 500+ breached passwords |
| POST | /generate |
Generate strong passwords |
| POST | /compare |
Compare two passwords side by side |
The /generate endpoint is my favourite — it returns strong passwords with their scores so you can show users exactly how secure the suggested password is.
How the Scoring Works
The score (0-100) is calculated from four components:
1. Length (0-30 points)
6 chars → 5 pts
8 chars → 10 pts
12 chars → 20 pts
16 chars → 25 pts
20+ chars → 30 pts
2. Character sets (0-28 points)
Each charset adds 7 points:
- Lowercase letters
- Uppercase letters
- Numbers
- Symbols
3. Unique character ratio (0-15 points)
Rewards passwords where characters don't repeat.
4. Entropy (0-15 points)
Calculated as: length × log2(pool_size)
Penalties applied for:
- Common passwords: -40 points
- Keyboard walks (qwerty, asdfgh): -20 points
- Repeated characters (aaa): -10 points
- Sequential numbers (123): -10 points
- All numbers or all letters: -15 points
Crack Time Estimation
This was the most interesting part to build. The formula:
function estimateCrackTime(password, charsets) {
let poolSize = 0;
if (charsets.has_lowercase) poolSize += 26;
if (charsets.has_uppercase) poolSize += 26;
if (charsets.has_numbers) poolSize += 10;
if (charsets.has_symbols) poolSize += 32;
const combinations = Math.pow(poolSize, password.length);
// Modern GPU: 10 billion guesses/second
const seconds = combinations / 1e10;
return formatTime(seconds);
}
The difference between online and offline attacks matters:
- Online attack — 10 million/sec (limited by server rate limiting)
- Offline attack — 10 billion/sec (attacker has the hash file)
password123 cracks in 5 months offline but 58 years online. That's why rate limiting matters even if your hashing is weak.
Breach Detection
The API checks against the 500 most common breached passwords — the ones that appear in every data breach dump.
const COMMON_PASSWORDS = new Set([
"password", "123456", "qwerty", "abc123", "monkey",
"letmein", "trustno1", "dragon", "baseball", "iloveyou",
// ... 490 more
]);
function checkBreach(password) {
const is_compromised = COMMON_PASSWORDS.has(password.toLowerCase());
return {
is_compromised,
risk_level: is_compromised ? "critical" : "low",
};
}
Tech Stack
- Runtime: Node.js + Express
- Hosting: Railway (free tier)
- Marketplace: RapidAPI
- Dependencies: express, cors, helmet, morgan, express-rate-limit
Zero paid APIs. Zero AI. The whole thing costs less than $5/month to run.
Score Guide
| Score | Grade | Strength |
|---|---|---|
| 80-100 | A | Very Strong |
| 60-79 | B | Strong |
| 40-59 | C | Moderate |
| 20-39 | D | Weak |
| 0-19 | F | Very Weak |
Recommended minimum for most apps: Grade B (60+)
Recommended for financial apps: Grade A (80+)
Try It
Live on RapidAPI — search Password Strength Security Scorer or find me at rapidapi.com/user/ruanmul04.
Free tier: 10 requests/month. No credit card required.
What's Next
Day 3 tomorrow — VAT Number Validator API.
Every e-commerce platform selling to Europe needs VAT validation. There are almost no good free options on RapidAPI. That's the gap I'm filling tomorrow.
Follow me here on dev.to to catch every day of the challenge. 🇿🇦
21 APIs in 21 days. Built in South Africa. Sold globally.
Top comments (0)