パスワードの強度判定
設定したパスワードの強度を判定する(短い/弱い/強い)モジュール
8文字以下を短いパスワード、8文字以上で連続した文字列は弱いパスワード、10文字以上で英数字が混在した文字列は強いパスワードとして判定。
パスワードに使う文字列は英数字に限定。
PHP
/**
*
* パスワードの強度判定
*
* @param string $password
* @return array
*/
function checkPassword($password)
{
// LESS 短いパスワード
$less_flg = FALSE;
$length = strlen($password);
if ($length < 8) {
$less_flg = TRUE;
}
// WARK 弱いパスワード
$weak_flg = FALSE;
if (! $less_flg) {
// 連続したパターン 11111111 12121212 123123123
if (preg_match('/^([0-9a-z]{1,3})\1+$/i', $password)) {
$weak_flg = TRUE;
} elseif (preg_match('/^[0-9]+$/', $password)) {
$num_flg = TRUE;
// 連続した数字 12345678 98765432
for ($i = 0; $i < $length; $i++) {
$num[$i] = substr($password, $i, 1);
if ($i > 0) {
$diff[$i] = $num[$i] - $num[$i - 1];
if ($i > 1) {
if ($diff[$i] != $diff[$i - 1]) {
$num_flg = FALSE;
break;
}
}
}
}
if ($num_flg) {
$weak_flg = TRUE;
}
} elseif (preg_match('/^[a-z]+$/i', $password)) {
$alpha_flg = TRUE;
// 連続したアルファベット abcdefgh zxywvuts
for ($i = 0; $i < $length; $i++) {
$dec[$i] = hexdec(substr($password, $i, 1));
if ($i > 0) {
$diff[$i] = $dec[$i] - $dec[$i - 1];
if ($i > 1) {
if ($diff[$i] != $diff[$i - 1]) {
$alpha_flg = FALSE;
break;
}
}
}
}
if ($alpha_flg) {
$weak_flg = TRUE;
}
}
if (! $weak_flg) {
// 指定のキーワードにマッチ
$ng_password = array('password', 'qwertyui');
foreach ($ng_password as $ngPassVal) {
if ($password == $ngPassVal) {
$weak_flg = TRUE;
break;
}
}
}
}
// STRONG 強いパスワード
$strong_flg = FALSE;
if (! $less_flg && ! $weak_flg) {
// 英数混在 10文字以上 a1b2c3d4e5 abcde12345
if (preg_match('/^(?=.*[0-9])(?=.*[a-z])[0-9a-z]{10,}$/i', $password)) {
$strong_flg = TRUE;
}
}
return array($less_flg, $weak_flg, $strong_flg);
}
使用例
PHP
list($less_flg, $weak_flg, $strong_flg) = checkPassword($password);
if ($less_flg) {
$strength = '短い';
} elseif ($weak_flg) {
$strength = '弱い';
} elseif ($strong_flg) {
$strength = '強い';
} else {
$strength = '普通';
}
サンプル
よく設定されるパスワードとしては名前+生年月日の組み合わせ(taro1121)、ログインIDやメールアドレスのローカル部(@前)をそのままパスワードに使っている場合があるので、制御可能であれば別途対応する。