本文目录导读:

我来为您提供一个完整的PHP支付密码校验解决方案,包含多种校验方式和安全措施。
基础支付密码校验类
<?php
class PaymentPasswordValidator {
// 密码最小长度
const MIN_LENGTH = 6;
// 密码最大长度
const MAX_LENGTH = 20;
// 常见弱密码列表
private static $weakPasswords = [
'123456', '12345678', '123456789', '111111',
'000000', 'abc123', 'password', 'qwerty',
'a123456', '123123', '666666', '888888'
];
/**
* 基础格式校验
* @param string $password 支付密码
* @return array ['valid' => bool, 'message' => string]
*/
public static function basicCheck($password) {
if (empty($password)) {
return ['valid' => false, 'message' => '支付密码不能为空'];
}
// 检查长度
if (strlen($password) < self::MIN_LENGTH) {
return ['valid' => false, 'message' => '支付密码长度不能少于' . self::MIN_LENGTH . '位'];
}
if (strlen($password) > self::MAX_LENGTH) {
return ['valid' => false, 'message' => '支付密码长度不能超过' . self::MAX_LENGTH . '位'];
}
// 检查是否为纯数字或字母数字组合
if (!preg_match('/^(?=.*[a-zA-Z0-9])[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};\':"\\\\|,.<>\/?]+$/', $password)) {
return ['valid' => false, 'message' => '支付密码包含非法字符'];
}
return ['valid' => true, 'message' => '校验通过'];
}
/**
* 复杂度检查
* @param string $password 支付密码
* @return array
*/
public static function complexityCheck($password) {
$check = self::basicCheck($password);
if (!$check['valid']) {
return $check;
}
// 检查是否包含数字
$hasNumber = preg_match('/[0-9]/', $password);
// 检查是否包含字母
$hasLetter = preg_match('/[a-zA-Z]/', $password);
// 建议包含数字和字母
if (!$hasNumber || !$hasLetter) {
return ['valid' => false, 'message' => '支付密码必须包含数字和字母'];
}
// 检查是否包含大写字母
$hasUppercase = preg_match('/[A-Z]/', $password);
// 检查是否包含小写字母
$hasLowercase = preg_match('/[a-z]/', $password);
// 检查是否包含特殊字符
$hasSpecial = preg_match('/[!@#$%^&*()_+\-=\[\]{};\':"\\\\|,.<>\/?]/', $password);
$score = 0;
if ($hasNumber) $score++;
if ($hasLetter) $score++;
if ($hasUppercase) $score++;
if ($hasLowercase) $score++;
if ($hasSpecial) $score++;
$strength = '';
if ($score <= 1) {
$strength = '弱';
} elseif ($score <= 3) {
$strength = '中等';
} else {
$strength = '强';
}
return [
'valid' => true,
'message' => '复杂度检查通过',
'strength' => $strength,
'score' => $score
];
}
/**
* 弱密码检查
* @param string $password 支付密码
* @return bool
*/
public static function isWeakPassword($password) {
// 检查是否在常见弱密码列表中
if (in_array($password, self::$weakPasswords)) {
return true;
}
// 检查是否为连续数字
if (preg_match('/^(?:0123456789|1234567890|0987654321)$/', $password)) {
return true;
}
// 检查是否为重复数字
if (preg_match('/^(\d)\1{2,}$/', $password)) {
return true;
}
// 检查是否包含连续数字
for ($i = 0; $i < strlen($password) - 2; $i++) {
$num1 = ord($password[$i]);
$num2 = ord($password[$i + 1]);
$num3 = ord($password[$i + 2]);
if (($num2 - $num1 == 1 && $num3 - $num2 == 1) ||
($num1 - $num2 == 1 && $num2 - $num3 == 1)) {
return true;
}
}
// 检查是否为重复字符模式
if (preg_match('/(.)\1{2,}/', $password)) {
// 最多允许重复2次,超过则视为弱密码
preg_match_all('/(.)\1{2,}/', $password, $matches);
if (count($matches[0]) > 0) {
return true;
}
}
return false;
}
/**
* 完整校验流程
* @param string $password 支付密码
* @param bool $strictMode 是否开启严格模式
* @return array
*/
public static function validate($password, $strictMode = true) {
// 基础校验
$basicCheck = self::basicCheck($password);
if (!$basicCheck['valid']) {
return $basicCheck;
}
// 弱密码检查
if (self::isWeakPassword($password)) {
return ['valid' => false, 'message' => '支付密码过于简单,请使用更复杂的密码'];
}
// 严格模式检查
if ($strictMode) {
$complexityCheck = self::complexityCheck($password);
if (!$complexityCheck['valid']) {
return $complexityCheck;
}
}
return ['valid' => true, 'message' => '支付密码设置成功'];
}
/**
* 密码强度评估(用于前端显示)
* @param string $password 支付密码
* @return array
*/
public static function strengthAssessment($password) {
$result = self::complexityCheck($password);
return [
'password' => $password,
'strength' => $result['strength'] ?? '弱',
'score' => $result['score'] ?? 0,
'valid' => $result['valid'] ?? false,
'message' => $result['message'] ?? '未知'
];
}
}
支付密码验证与加密
<?php
class PaymentPasswordManager {
// 加密密钥(应该从配置文件读取)
private static $encryptionKey = 'your-secret-key-here';
/**
* 加密支付密码
* @param string $password 原始密码
* @return string 加密后的密码
*/
public static function encrypt($password) {
// 使用PHP内置的密码哈希函数
return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}
/**
* 验证支付密码
* @param string $password 输入的密码
* @param string $hash 存储的哈希值
* @return bool
*/
public static function verify($password, $hash) {
return password_verify($password, $hash);
}
/**
* 检查密码是否需要重新哈希
* @param string $hash 存储的哈希值
* @return bool
*/
public static function needsRehash($hash) {
return password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12]);
}
/**
* 存储支付密码(应存储在数据库中)
* @param int $userId 用户ID
* @param string $password 支付密码
* @return bool
*/
public static function storePaymentPassword($userId, $password) {
// 先进行校验
$validation = PaymentPasswordValidator::validate($password);
if (!$validation['valid']) {
return false;
}
// 加密密码
$hashedPassword = self::encrypt($password);
// 在这里执行数据库存储
// PDO 示例:
/*
$pdo = getDatabaseConnection();
$stmt = $pdo->prepare("INSERT INTO payment_passwords (user_id, hash, created_at) VALUES (?, ?, NOW())");
$result = $stmt->execute([$userId, $hashedPassword]);
return $result;
*/
// 模拟存储成功
return true;
}
/**
* 验证支付密码输入
* @param int $userId 用户ID
* @param string $password 输入的密码
* @return array
*/
public static function validatePaymentPassword($userId, $password) {
// 从数据库获取存储的哈希值
// 示例:$hash = getPasswordHashFromDatabase($userId);
$hash = '$2y$12$YourStoredHashHere'; // 示例哈希
if (self::verify($password, $hash)) {
// 验证客户端IP、设备信息等(如果需要)
return [
'valid' => true,
'message' => '支付密码验证成功'
];
} else {
return [
'valid' => false,
'message' => '支付密码错误'
];
}
}
/**
* 尝试次数限制(防暴力破解)
* @param int $userId 用户ID
* @return bool 是否允许尝试
*/
public static function checkAttemptLimit($userId) {
// 获取用户尝试次数
$attemptCount = getAttemptCountFromRedis($userId);
$lastAttemptTime = getLastAttemptTimeFromRedis($userId);
// 如果超过5次尝试,锁定15分钟
if ($attemptCount >= 5) {
$lockTime = strtotime($lastAttemptTime) + 900; // 15分钟
if (time() < $lockTime) {
return false;
} else {
// 重置尝试次数
resetAttemptCount($userId);
return true;
}
}
return true;
}
}
前端密码强度即时检查
<?php
// 用于前端验证的API端点
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'validate_payment_password') {
$password = $_POST['password'] ?? '';
// 使用PaymentPasswordValidator进行校验
$result = PaymentPasswordValidator::validate($password, false); // 非严格模式
// 如果通过基础校验,进行强度评估
if ($result['valid']) {
$strength = PaymentPasswordValidator::strengthAssessment($password);
echo json_encode($strength);
} else {
echo json_encode($result);
}
}
if ($_POST['action'] === 'check_strength') {
$password = $_POST['password'] ?? '';
$strength = PaymentPasswordValidator::strengthAssessment($password);
echo json_encode($strength);
}
exit;
}
?>
<!-- 前端HTML示例 -->
<!DOCTYPE html>
<html>
<head>支付密码设置</title>
<style>
.password-strength {
display: block;
height: 10px;
margin-top: 10px;
background-color: #eee;
}
.strength-bar {
height: 100%;
width: 0;
transition: width 0.3s;
}
#strength-label {
margin-top: 5px;
font-size: 12px;
color: #666;
}
</style>
</head>
<body>
<form id="payment-password-form">
<label for="password">支付密码:</label>
<input type="password" id="password" name="password"
placeholder="请输入支付密码" autocomplete="new-password">
<div class="password-strength">
<div class="strength-bar" id="strength-bar"></div>
</div>
<div id="strength-label"></div>
<div id="message"></div>
<button type="submit" id="submit-btn">提交</button>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('#password').on('keyup', function() {
var password = $(this).val();
// 实时检查密码强度
$.ajax({
url: window.location.href,
method: 'POST',
data: {
action: 'check_strength',
password: password
},
success: function(response) {
var data = JSON.parse(response);
updateStrengthUI(data);
}
});
});
function updateStrengthUI(data) {
var color, width, labelText;
switch(data.strength) {
case '强':
color = '#27ae60';
width = '100%';
labelText = '强';
break;
case '中等':
color = '#f39c12';
width = '60%';
labelText = '中等';
break;
default:
color = '#e74c3c';
width = '30%';
labelText = '弱';
break;
}
$('#strength-bar').css({
'width': width,
'background-color': color
});
$('#strength-label').text('密码强度:' + labelText);
if (data.valid) {
$('#submit-btn').prop('disabled', false);
$('#message').text('密码设置有效').css('color', '#27ae60');
} else {
$('#submit-btn').prop('disabled', true);
$('#message').text(data.message).css('color', '#e74c3c');
}
}
// 表单提交
$('#payment-password-form').on('submit', function(e) {
e.preventDefault();
var password = $('#password').val();
$.ajax({
url: window.location.href,
method: 'POST',
data: {
action: 'validate_payment_password',
password: password
},
success: function(response) {
var data = JSON.parse(response);
$('#message').text(data.message).css(
'color', data.valid ? '#27ae60' : '#e74c3c'
);
}
});
});
});
</script>
</body>
</html>
完整的支付密码校验函数
<?php
/**
* 完整的支付密码校验函数
* @param string $password 支付密码
* @param array $options 配置选项
* @return array 校验结果
*/
function validatePaymentPassword($password, $options = []) {
// 默认配置
$defaultOptions = [
'min_length' => 6,
'max_length' => 20,
'require_letter_and_number' => true,
'check_weak_password' => true,
'strict_mode' => false
];
$options = array_merge($defaultOptions, $options);
$errors = [];
$warnings = [];
// 1. 基础检查
if (empty($password) || strlen($password) < 1) {
$errors[] = '支付密码不能为空';
}
// 2. 长度检查
$len = strlen($password);
if ($len < $options['min_length']) {
$errors[] = "支付密码长度不能少于{$options['min_length']}位";
}
if ($len > $options['max_length']) {
$errors[] = "支付密码长度不能超过{$options['max_length']}位";
}
// 3. 字符类型检查
$hasNumber = (bool) preg_match('/[0-9]/', $password);
$hasLetter = (bool) preg_match('/[a-zA-Z]/', $password);
$hasUpperCase = (bool) preg_match('/[A-Z]/', $password);
$hasLowerCase = (bool) preg_match('/[a-z]/', $password);
$hasSpecial = (bool) preg_match('/[!@#$%^&*()_+\-=\[\]{};\':"\\\\|,.<>\/?]/', $password);
if ($options['require_letter_and_number'] && (!$hasNumber || !$hasLetter)) {
$errors[] = '支付密码必须包含数字和字母';
}
if ($options['strict_mode'] && !$hasUpperCase) {
$warnings[] = '建议包含大写字母';
}
if ($options['strict_mode'] && !$hasSpecial) {
$warnings[] = '建议包含特殊字符';
}
// 4. 弱密码检查
if ($options['check_weak_password']) {
$weakPatterns = [
'/^123456$/', // 连续数字
'/^654321$/', // 倒序数字
'/^111111$/', // 重复数字
'/^000000$/',
'/^abcdef$/', // 连续字母
'/^a1b2c3$/' // 简单模式
];
foreach ($weakPatterns as $pattern) {
if (preg_match($pattern, $password)) {
$errors[] = '支付密码过于简单';
break;
}
}
}
// 5. 相似检查(可选)
if (isset($options['old_password']) && $password === $options['old_password']) {
$errors[] = '新支付密码不能与当前支付密码相同';
}
// 6. 结果返回
if (!empty($errors)) {
return [
'valid' => false,
'errors' => $errors,
'warnings' => $warnings,
'message' => $errors[0]
];
}
return [
'valid' => true,
'errors' => [],
'warnings' => $warnings,
'message' => '校验通过'
];
}
// 使用示例
$password = 'Abc123456';
$result = validatePaymentPassword($password, ['strict_mode' => true]);
if ($result['valid']) {
echo "支付密码有效:{$result['message']}";
if (!empty($result['warnings'])) {
echo "\n警告:" . implode("、", $result['warnings']);
}
} else {
echo "支付密码无效:{$result['message']}";
}
这套支付密码校验方案提供了:
- 基础格式校验 - 长度、字符类型
- 复杂度检查 - 数字、字母、特殊字符组合
- 弱密码检测 - 常见弱密码、连续模式
- 安全建议 - 大小写、特殊字符
- 前端实时反馈 - 密码强度显示
- 防暴力破解 - 尝试次数限制
- 安全存储 - 使用bcrypt加密
根据实际需求,可以选择适合的校验级别和方法。