パスワードポリシー

安全なパスワードの要件と管理ルールを定義し、NIST ガイドラインに基づくセキュリティ方針

認証セキュリティ

パスワードポリシーとは

パスワードポリシーは、ユーザーが設定するパスワードの要件 (長さ、複雑さ) と管理ルール (保存方法、有効期限) を定義するセキュリティ方針である。NIST SP 800-63B (2017 年改訂) が現代のベストプラクティスを定めている。

NIST の推奨 (従来の常識を覆す)

項目 従来の常識 NIST 推奨
最小文字数 8 文字 8 文字以上 (15 文字以上を推奨)
複雑さの要件 大文字+小文字+数字+記号を強制 強制しない (長さを重視)
定期変更 90 日ごとに変更 漏洩が疑われない限り変更不要
秘密の質問 使用 使用しない
パスワードヒント 使用 使用しない

複雑さの強制は、ユーザーが P@ssw0rd! のような予測可能なパターンを使う原因になる。長いパスフレーズ (correct horse battery staple) の方が安全で覚えやすい。

パスワードの保存

import { hash, verify } from '@node-rs/argon2';

// ✅ Argon2id でハッシュ化して保存
const passwordHash = await hash(password, {
  memoryCost: 65536,  // 64MB
  timeCost: 3,
  parallelism: 4,
});

// 検証
const isValid = await verify(passwordHash, inputPassword);
アルゴリズム 推奨度 特徴
Argon2id 最推奨 メモリハード、GPU 攻撃に強い
bcrypt 推奨 広くサポート、72 バイト制限
scrypt 推奨 メモリハード
SHA-256 + salt 非推奨 高速すぎてブルートフォースに弱い
MD5 / SHA-1 禁止 脆弱性あり

漏洩パスワードのチェック

Have I Been Pwned (HIBP) の API で、ユーザーが設定しようとしているパスワードが過去の漏洩データに含まれていないかチェックする。

import { createHash } from 'crypto';

async function isPasswordBreached(password: string): Promise<boolean> {
  const sha1 = createHash('sha1').update(password).digest('hex').toUpperCase();
  const prefix = sha1.slice(0, 5);
  const suffix = sha1.slice(5);

  const res = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`);
  const text = await res.text();
  return text.includes(suffix);
}

k-Anonymity モデルにより、パスワード全体を API に送信しない。

パスワードポリシーの理解を深めるには関連書籍が参考になる。

関連用語