Skip to content

zxcvbn

パスワードの強度を推定してくれるライブラリ。
バリデーションfield_validator で、新しいパスワードの複雑さチェックに使ってる。


インストール

uv コマンドでインストールする。

uv add zxcvbn


使い方

zxcvbn の引数に検査したいパスワードを渡すだけ。下のコードでは、検査結果をまるごと表示している。

from zxcvbn import zxcvbn
import json

password = "password123"
results = zxcvbn(password)
print(json.dumps(results, indent=2, ensure_ascii=False, default=str))

{
  "password": "password123",
  "guesses": "596",
  "guesses_log10": 2.775246259740236,
  "sequence": [
    {
      "pattern": "dictionary",
      "i": 0,
      "j": 10,
      "token": "password123",
      "matched_word": "password123",
      "rank": 595,
      "dictionary_name": "passwords",
      "reversed": false,
      "l33t": false,
      "base_guesses": 595,
      "uppercase_variations": 1,
      "l33t_variations": 1,
      "guesses": 595,
      "guesses_log10": 2.7745169657285493
    }
  ],
  "calc_time": "0:00:00.000904",
  "crack_times_seconds": {
    "online_throttling_100_per_hour": "21456.00000000000119104726082",
    "online_no_throttling_10_per_second": "59.6",
    "offline_slow_hashing_1e4_per_second": "0.0596",
    "offline_fast_hashing_1e10_per_second": "5.96E-8"
  },
  "crack_times_display": {
    "online_throttling_100_per_hour": "6 hours",
    "online_no_throttling_10_per_second": "60 seconds",
    "offline_slow_hashing_1e4_per_second": "less than a second",
    "offline_fast_hashing_1e10_per_second": "less than a second"
  },
  "score": 0,
  "feedback": {
    "warning": "This is a very common password.",
    "suggestions": [
      "Add another word or two. Uncommon words are better."
    ]
  }
}

Score

上の出力にも出てる score を元にパスワードの強度を検査できる。 score は 0〜4 の5段階で、大きいほど強い。

from zxcvbn import zxcvbn

passwords = ["password123", "correcthorsebatterystaple", "Tr0ub4dor&3", "P@ssw0rd!"]

for password in passwords:
    results = zxcvbn(password)
    if results["score"] >= 3:
        print(f"Password is strong: {password}")
    else:
        print(f"Password is weak: {password}")

Password is weak: password123
Password is strong: correcthorsebatterystaple
Password is strong: Tr0ub4dor&3
Password is weak: P@ssw0rd!

Note

辞書にある単語や P@ssw0rd! のような単純な置き換え( leet )は、長くても弱いと判定される。逆に correcthorsebatterystaple のような単語の羅列は強いと判定される。


FastAPI で API を作成

パスワードを受け取って強度スコアを返すエンドポイントを作成してみる。

# main.py
from fastapi import FastAPI, Body
from zxcvbn import zxcvbn

app = FastAPI()


@app.post("/check-password")
def check_password(password: str = Body(..., embed=True)):
    results = zxcvbn(password)
    status = "strong" if results["score"] >= 3 else "weak"

    return {"Password": status}

curl で確認。

% curl -X 'POST' \
  'http://127.0.0.1:8000/check-password' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"password": "password123"}'
{"Password":"weak"}

% curl -X 'POST' \
  'http://127.0.0.1:8000/check-password' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"password": "correcthorsebatterystaple"}'
{"Password":"strong"}