PHPでパスワードの強度を調べる

(1/1)
強いパスワードをつくる」では、強いパスワードをつくる方法を説明した。では、実際につくったプログラムの強度はどのくらいだろうか――。
今回は、文字の種類や長さのほか、既存単語かどうか、パスワードの強度を調べるPHPプログラムを作ってみることにする。なお、入力したパスワードをデータベースやファイル、キャッシュに蓄えることはしないが、ネット越しにパスワードが行き来するので、万が一のことを考え、ここで検査したパスワードを本番認証には使わないようにしてほしい。

(2025年12月28日)PHP8.5対応:curl_closeを使わない

目次

サンプル・プログラムの実行例

PHPでパスワードの強度を調べる

サンプル・プログラムのダウンロード

圧縮ファイルの内容
passwordStrength.phpサンプル・プログラム本体
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
passwordStrength.php 更新履歴
バージョン 更新日 内容
1.3.0 2025/12/28 PHP8.5対応:curl_closeを使わない
1.2.1 2023/03/09 bug-fix
1.2.0 2023/02/25 判定方法変更,リファラチェック改良
1.1.0 2023/02/05 pahooInputDataクラス導入
1.0.0 2020/02/01 初版
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加

パスワードの強度

ここでは、パスワードの強度を下記のように定義する。数字が大きいほど強い。
  1. 数字だけ
  2. 英数6文字以下
  3. Wikipediaの見出しに存在する
  4. 記号が含まれていない
  5. 記号が含まれている

解説:文字列の長さ

文字列の長さが PASSWORD_LENGTH_MIN 未満か、または PASSWORD_LENGTH_MAX 超であるかどうかを調べるユーザー関数が [# validateLength:title= validateLength] である。
ここで、PASSWORD_LENGTH_MINを8、PASSWORD_LENGTH_MAXを64としたのは、NIST(National Institute of Standards and Technology;米国立標準技術研究所)のセキュリティ文書「NIST Special Publication 800-63B」の「5.1.1 記憶シークレット」を引用している。

passwordStrength.php

 129: /**
 130:  * 指定した文字列の長さが指定した範囲内かどうかを求める.
 131:  * @return  bool TRUE:範囲内でない/FALSE:である
 132: */
 133: function validateLength($str) {
 134:     $len = strlen($str);
 135:     return (($len < PASSWORD_LENGTH_MIN|| ($len > PASSWORD_LENGTH_MAX));
 136: }

解説:数字だけ

数字だけからなる文字列かどうかを調べるユーザー関数が isNumber である。正規表現を使って判定している。

passwordStrength.php

 138: /**
 139:  * 指定した文字列が数字だけかどうかを求める.
 140:  * @param   string $str 文字列
 141:  * @return  bool TRUE:数字だけである/FALSE:ではない
 142: */
 143: function isNumber($str) {
 144:     return preg_match('/^[0-9]+$/ui', $str? TRUE : FALSE;
 145: }

解説:英数字だけ

英数字だけからなる文字列かどうかを調べるユーザー関数が isAlphanumeric である。これも正規表現を使って判定している。

passwordStrength.php

 147: /**
 148:  * 指定した文字列が英数字だけかどうかを求める.
 149:  * @param   string $str 文字列
 150:  * @return  bool TRUE:英数6文字以下である/FALSE:ではない
 151: */
 152: function isAlphanumeric($str) {
 153:     return preg_match('/^[A-Z|a-z|0-9]$/ui', $str? TRUE : FALSE;
 154: }

解説:Wikipediaの見出しに存在する

既存の単語かどうかを調べるのに、Wikipedia の見出しに存在するかどうかを調べることにした。このためのユーザー関数が isWikipedia である。
文字列からWikipediaの見出しURLを生成し、「PHPでリンク切れを調べる」で作ったユーザー関数 getHttpResponseCodeSize を使って存在するかどうか判定する。

passwordStrength.php

 215: /**
 216:  * Wikipediaの見出しに存在する文字列かどうか
 217:  * @param   string $str 文字列
 218:  * @return  bool TRUE:存在する/FALSE:しない
 219: */
 220: function isWikipedia($str) {
 221:     $str = urlencode($str);
 222:     $url  = 'https://en.wikipedia.org/wiki/' . $str;
 223:     list($code, $size) = getHttpResponseCodeSize($url);
 224: 
 225:     return ($code == 200? TRUE : FALSE;
 226: }

解説:記号を含まない

記号を含まない文字列かどうかを調べるユーザー関数が isContainNoSymbol である。これも正規表現を使って判定している。

passwordStrength.php

 228: /**
 229:  * 指定した文字列が記号を含まないかどうかを求める.
 230:  * @param   string $str 文字列
 231:  * @return  bool TRUE:記号が含まれていない/FALSE:含まれている
 232: */
 233: function isContainNoSymbol($str) {
 234:     return preg_match('/^[a-z|0-9]+$/ui', $str? TRUE : FALSE;
 235: }

解説:パスワードの強度を算出

以上のユーザー関数を順次呼び出し、パスワードの強度を算出するユーザー関数が getPasswordStrength である。

passwordStrength.php

 237: /**
 238:  * パスワードの強度を算出
 239:  * @param   string $psw パスワード
 240:  * @return  int 強度
 241:  *              1:数字だけ
 242:  *              2:英数字のみ
 243:  *              3:Wikipediaの見出しに存在する
 244:  *              4:記号が含まれていない
 245:  *              5:記号が含まれている
 246: */
 247: function getPasswordStrength($psw) {
 248:     // 強度と判定関数の対応表
 249:     $table = array(
 250: 0 => 'validateLength',
 251: 1 => 'isNumber',
 252: 2 => 'isAlphanumeric',
 253: 3 => 'isWikipedia',
 254: 4 => 'isContainNoSymbol'
 255: );
 256: 
 257:     // 入力値(パスワード)の検査
 258:     $str = preg_replace('/[ \t]+/ui', '', $psw);    // 空白を除く
 259: 
 260:     // パスワード強度判定
 261:     $res = 5;
 262:     foreach ($table as $key=>$func) {
 263:         if ($func($str)) {
 264:             $res = $key;
 265:             break;
 266:         }
 267:     }
 268:     return $res;
 269: }

参考サイト

(この項おわり)
header