この文書では, Webサービスでのユーザのパスワードについての標準を規定する.
サービスは, パスワードの最小の長さを8文字にする必要がある. ただし, 8文字のパスワードでは機会損失の可能性が無視できない場合は, 情報セキュリティ委員会で検討し例外を認める場合がある.
サービスは, パスワードの最大の長さを32〜100文字にする必要がある.
後述するハッシュを利用したパスワード情報の保管を行なう場合, 最大値を規定しない場合や最大値が大きい場合DoS攻撃が可能になる恐れがある.
サービスは, ASCIIの英字大文字, 英字小文字, 数字がパスワードに利用できなければならない. その他の文字種も利用可能にしてもよい. ただし, パスワードの文字種の増加はパスワード長の増加ほどはセキュリティを向上しないことに注意.
サービスは, パスワード変更機能を設けなければならない.
サービスは, パスワードリマインダ機能を設けなければならない. ユーザ専用の一時URLを発行しユーザの登録メールアドレスにメールで通知する方式での実装を行なう必要がある. 一時URLの有効期限は1日以下にしなければならない.
サービスのユーザ層によっては, パスワードリマインダ機能でパスワードそのものをユーザにメールで通知する方法を採用してもよい.
サービスは, パスワードの期限を設けてはならない. 同じ強度のパスワードが破られる可能性はパスワードの変更後も変化しないので, パスワードが漏れた可能性がない限りパスワードを変更する理由はない.
サービスは, 以下の啓蒙を定期的に行なわなければならない.
サービスは, サイトへのログインに必要なパスワード以外の認証を行なわないようにする必要がある. たとえば, 生年月日やいわゆる秘密の質問を利用した認証を行ってはならない.
ただし, 金銭やポイントを利用するサービスで単にパスワードのみで認証を行なうと他サイトからユーザのパスワードが漏れた場合に不正に繋がる場合には, 取引用の認証方法を別途利用してもよい. 新規に実装する場合は, 取引用の別パスワードをユーザに指定される方法を推奨する. 取引用パスワードの長さなどについてもこの標準に従うこと.
秘密の質問を利用する場合は, ユーザ本人以外の人間(家族を含む)にはわかりにくいものを利用しなければならない. また他のサイトで利用している設問は利用しないほうがよい.
サービスは, パスワードをそのままDBなどに保存してはならない. 以下の方式を利用すること.
サービスが利用するパスワード保存方式として, パスワードをハッシュ関数を利用して加工しそれを保存する以下の方式を推奨する. 詳細は, Cryptography Engineering(Ferguson, Schneier, Kohno, p304)を参照.
DBに保存する情報は以下の通りである. それぞれの詳細は後述する.
利用しているハッシュ関数に脆弱性が見つかった場合には, 新規に保存するパスワード情報よりアルゴリズムを変更できるようシステムを設計しなければならない. このため, パスワード情報として, サルト, ハッシュ化されたパスワードに加えてアルゴリズム情報(のID)も保存しなければならない.
サルトにはハッシュ関数の出力と同じ長さの文字列を利用する. 十分なエントロピーを確保するために, サルトの生成は疑似乱数ではない乱数を用いて生成する必要がある. GNU/Linuxの場合乱数源として /dev/urandom を用いればよい.
DBへの格納の際は, バイナリ文字列を入れないため base64 すること. バイナリ文字列をDBに格納するとDBの移行などの際にチェックが面倒となる.
以下にPHPのコード断片を示す:
$x = '';
for($i = 0; $i < $iter; ++$i) {
$x = hash('sha256',
$x . $password . $salt, true);
}
$hashed_password = base64_encode($x);
上記コードでは SHA-256 を利用している. base64しているのはDBにバイナリ文字列を入れないためである.
上記コードの $iter のこと. 5000回以上を推奨する. 回数が多いほどパスワードの照合に時間がかかるようになる. サーバの性能にあわせて設定すること.