基于Python实现一个专业的密码强度检测器

Written by

in

文章目录
  • 这是一个专业的密码强度检测工具,用于评估密码的安全性和强度。该工具具备以下核心功能: 多维度强度评估: 长度检测(密码长度要求) 字符类型检测(大小写字母、数字、特殊字符) 字典攻击防护(常见密码和弱密码检测) 模式识别(键盘序列、重复字符等) 熵值计算(密码随机性评估) 详细评分系统: 综合评分机制(0-100分制) 分项评分展示(长度、复杂度、模式等) 强度等级划分(弱、中、强、 very strong) 改进建议提供 自定义策略支持: 可配置的密码策略 自定义评分权重 特定行业标准支持(如NIST、PCI DSS等) 黑名单词汇库 批量检测功能: 支持批量密码检测 密码文件批量分析 检测结果统计报告 弱密码列表导出 安全防护机制: 内存安全处理(避免密码明文存储) 输入安全验证 防止暴力 破解保护 安全日志记录
  • #!/usr/bin/env python3 # -*- coding: utf-8 -*- “”” 密码强度检测器 功能:评估密码的安全性和强度 作者:Cline 版本:1.0 “”” import argparse import sys import json import logging import os import re import math from datetime import datetime from typing import Dict, List, Tuple, Optional import hashlib import secrets # 配置日志 logging.basicConfig( level=logging.INFO, format=’%(asctime)s – %(levelname)s – %(message)s’, handlers=[ logging.FileHandler(‘password_checker.log’), logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger(__name__) class PasswordSecurityError(Exception): “””密码安全异常类””” pass class PasswordValidationError(Exception): “””密码验证异常类””” pass class PasswordStrengthChecker: def __init__(self, config: Dict[str, any] = None): # 默认配置 self.default_config = { “min_length”: 8, “max_length”: 128, “require_uppercase”: True, “require_lowercase”: True, “require_digits”: True, “require_special_chars”: True, “min_special_chars”: 1, “blacklist_words”: [ “password”, “123456”, “qwerty”, “admin”, “welcome”, “login”, “root”, “guest”, “user”, “test” ], “keyboard_patterns”: [ “qwerty”, “asdf”, “zxcv”, “1234”, “abcd” ], “scoring_weights”: { “length”: 0.3, “complexity”: 0.4, “patterns”: 0.2, “entropy”: 0.1 } } # 合并配置 self.config = {**self.default_config, **(config or {})} # 特殊字符集合 self.special_chars = “!@#$%^&*()_+-=[]{}|;:,.<>?” # 检测结果统计 self.stats = { “total_checked”: 0, “strong_passwords”: 0, “medium_passwords”: 0, “weak_passwords”: 0, “very_weak_passwords”: 0 } def calculate_entropy(self, password: str) -> float: “””计算密码熵值””” if not password: return 0.0 # 计算字符集大小 charset_size = 0 if re.search(r'[a-z]’, password): charset_size += 26 if re.search(r'[A-Z]’, password): charset_size += 26 if re.search(r'[0-9]’, password): charset_size += 10 if re.search(r'[^a-zA-Z0-9]’, password): charset_size += len(self.special_chars) # 计算熵值 if charset_size > 0: entropy = len(password) * math.log2(charset_size) return min(entropy, 100.0) # 限制最大值 return 0.0 def check_length(self, password: str) -> Tuple[int, str]: “””检查密码长度””” length = len(password) min_len = self.config[“min_length”] max_len = self.config[“max_length”] if length < min_len: return 0, f”密码长度不足,至少需要 {min_len} 个字符” elif length > max_len: return 0, f”密码长度过长,最多允许 {max_len} 个字符” else: # 长度评分(线性增长) score = min(100, (length / max_len) * 100) return int(score), f”密码长度合适 ({length} 个字符)” def check_complexity(self, password: str) -> Tuple[int, str]: “””检查密码复杂度””” score = 0 feedback = [] # 检查小写字母 if re.search(r'[a-z]’, password): score += 25 elif self.config[“require_lowercase”]: feedback.append(“缺少小写字母”) # 检查大写字母 if re.search(r'[A-Z]’, password): score += 25 elif self.config[“require_uppercase”]: feedback.append(“缺少大写字母”) # 检查数字 if re.search(r'[0-9]’, password): score += 25 elif self.config[“require_digits”]: feedback.append(“缺少数字”) # 检查特殊字符 special_count = len(re.findall(r'[^a-zA-Z0-9]’, password)) if special_count >= self.config[“min_special_chars”]: score += 25 elif self.config[“require_special_chars”]: feedback.append(f”特殊字符不足,至少需要 {self.config[‘min_special_chars’]} 个”) if not feedback: feedback_msg = “字符类型齐全” else: feedback_msg = “、”.join(feedback) return score, feedback_msg def check_patterns(self, password: str) -> Tuple[int, str]: “””检查密码模式””” score = 100 feedback = [] # 检查黑名单词汇 password_lower = password.lower() for word in self.config[“blacklist_words”]: if word in password_lower: score -= 30 feedback.append(f”包含常见弱密码词汇: {word}”) # 检查键盘序列 for pattern in self.config[“keyboard_patterns”]: if pattern in password_lower or pattern[::-1] in password_lower: score -= 20 feedback.append(f”包含键盘序列: {pattern}”) # 检查重复字符 if re.search(r'(.)1{2,}’, password): score -= 15 feedback.append(“包含过多重复字符”) # 检查连续字符 consecutive_count = 0 for i in range(len(password) – 2): if ord(password[i+1]) == ord(password[i]) + 1 and ord(password[i+2]) == ord(password[i]) + 2: consecutive_count += 1 if consecutive_count > 0: score -= 10 * consecutive_count feedback.append(f”包含 {consecutive_count} 组连续字符”) # 确保分数不低于0 score = max(0, score) if not feedback: feedback_msg = “未发现明显模式问题” else: feedback_msg = “、”.join(feedback) return score, feedback_msg def evaluate_password_strength(self, password: str) -> Dict[str, any]: “””评估密码强度””” if not password: raise PasswordValidationError(“密码不能为空”) # 基本验证 if len(password) > self.config[“max_length”]: raise PasswordValidationError(f”密码长度不能超过 {self.config[‘max_length’]} 个字符”) # 各项检测 length_score, length_feedback = self.check_length(password) complexity_score, complexity_feedback = self.check_complexity(password) patterns_score, patterns_feedback = self.check_patterns(password) entropy_score = self.calculate_entropy(password) # 计算综合得分 weights = self.config[“scoring_weights”] total_score = ( length_score * weights[“length”] + complexity_score * weights[“complexity”] + patterns_score * weights[“patterns”] + entropy_score * weights[“entropy”] ) # 确定强度等级 if total_score >= 80: strength_level = “very_strong” strength_desc = “非常强” elif total_score >= 60: strength_level = “strong” strength_desc = “强” elif total_score >= 40: strength_level = “medium” strength_desc = “中等” else: strength_level = “weak” strength_desc = “弱” # 更新统计 self.stats[“total_checked”] += 1 if strength_level == “very_strong”: self.stats[“strong_passwords”] += 1 elif strength_level == “strong”: self.stats[“strong_passwords”] += 1 elif strength_level == “medium”: self.stats[“medium_passwords”] += 1 else: self.stats[“weak_passwords”] += 1 result = { “password”: self.mask_password(password), “score”: round(total_score, 2), “strength_level”: strength_level, “strength_description”: strength_desc, “details”: { “length”: { “score”: length_score, “feedback”: length_feedback }, “complexity”: { “score”: complexity_score, “feedback”: complexity_feedback }, “patterns”: { “score”: patterns_score, “feedback”: patterns_feedback }, “entropy”: { “score”: round(entropy_score, 2), “bits”: round(math.log2(len(password) or 1), 2) if password else 0 } }, “recommendations”: self.generate_recommendations( length_score, complexity_score, patterns_score ), “timestamp”: datetime.now().isoformat() } return result def mask_password(self, password: str) -> str: “””掩码密码显示””” if len(password) <= 4: return “*” * len(password) else: return password[:2] + “*” * (len(password) – 4) + password[-2:] def generate_recommendations(self, length_score: int, complexity_score: int, patterns_score: int) -> List[str]: “””生成改进建议””” recommendations = [] if length_score < 80: recommendations.append(“增加密码长度,建议至少12个字符”) if complexity_score < 80: recommendations.append(“使用更多类型的字符(大小写字母、数字、特殊符号)”) if patterns_score < 80: recommendations.append(“避免使用常见词汇、键盘序列和重复字符”) if not recommendations: recommendations.append(“密码强度良好,继续保持”) return recommendations def check_password_list(self, passwords: List[str]) -> List[Dict[str, any]]: “””批量检查密码列表””” results = [] for i, password in enumerate(passwords): try: result = self.evaluate_password_strength(password.strip()) results.append(result) logger.info(f”已检查第 {i+1} 个密码”) except Exception as e: logger.error(f”检查第 {i+1} 个密码时出错: {str(e)}”) results.append({ “password”: self.mask_password(password.strip()), “error”: str(e), “timestamp”: datetime.now().isoformat() }) return results def load_passwords_from_file(self, file_path: str) -> List[str]: “””从文件加载密码列表””” try: with open(file_path, ‘r’, encoding=’utf-8′) as f: passwords = [line.strip() for line in f if line.strip()] logger.info(f”从文件加载了 {len(passwords)} 个密码”) return passwords except FileNotFoundError: logger.error(f”密码文件不存在: {file_path}”) raise PasswordSecurityError(f”文件未找到: {file_path}”) except Exception as e: logger.error(f”加载密码文件时出错: {str(e)}”) raise PasswordSecurityError(f”文件加载失败: {str(e)}”) def save_results(self, results: List[Dict[str, any]], output_file: str): “””保存检测结果””” try: # 确保输出目录存在 output_dir = os.path.dirname(output_file) if os.path.dirname(output_file) else ‘.’ os.makedirs(output_dir, exist_ok=True) with open(output_file, ‘w’, encoding=’utf-8′) as f: json.dump(results, f, indent=2, ensure_ascii=False) logger.info(f”检测结果已保存到 {output_file}”) except Exception as e: logger.error(f”保存检测结果时出错: {str(e)}”) raise PasswordSecurityError(f”结果保存失败: {str(e)}”) def generate_report(self, results: List[Dict[str, any]]) -> Dict[str, any]: “””生成检测报告””” weak_passwords = [r for r in results if r.get(“strength_level”) in [“weak”, “very_weak”]] medium_passwords = [r for r in results if r.get(“strength_level”) == “medium”] strong_passwords = [r for r in results if r.get(“strength_level”) in [“strong”, “very_strong”]] report = { “summary”: { “total_passwords”: len(results), “very_strong”: len([r for r in results if r.get(“strength_level”) == “very_strong”]), “strong”: len([r for r in results if r.get(“strength_level”) == “strong”]), “medium”: len(medium_passwords), “weak”: len([r for r in results if r.get(“strength_level”) == “weak”]), “very_weak”: len([r for r in results if r.get(“strength_level”) == “very_weak”]) }, “statistics”: self.stats, “weak_passwords”: weak_passwords[:10], # 只显示前10个弱密码 “recommendations”: [ “定期更换密码”, “使用密码管理器生成和存储复杂密码”, “启用多因素认证”, “避免在多个账户使用相同密码” ], “timestamp”: datetime.now().isoformat() } return report def print_result(self, result: Dict[str, any]): “””打印检测结果””” print(“n” + “=”*60) print(“密码强度检测结果”) print(“=”*60) print(f”密码: {result[‘password’]}”) print(f”综合得分: {result[‘score’]}/100″) print(f”强度等级: {result[‘strength_description’]}”) print(“-“*60) print(“详细分析:”) print(f” 长度检测: {result[‘details’][‘length’][‘score’]}/100 – {result[‘details’][‘length’][‘feedback’]}”) print(f” 复杂度检测: {result[‘details’][‘complexity’][‘score’]}/100 – {result[‘details’][‘complexity’][‘feedback’]}”) print(f” 模式检测: {result[‘details’][‘patterns’][‘score’]}/100 – {result[‘details’][‘patterns’][‘feedback’]}”) print(f” 熵值检测: {result[‘details’][‘entropy’][‘score’]}/100 ({result[‘details’][‘entropy’][‘bits’]} bits)”) print(“-“*60) print(“改进建议:”) for i, rec in enumerate(result[‘recommendations’], 1): print(f” {i}. {rec}”) print(“=”*60) def print_report(self, report: Dict[str, any]): “””打印检测报告””” print(“n” + “=”*60) print(“密码强度检测报告”) print(“=”*60) print(f”检测时间: {report[‘timestamp’]}”) print(“-“*60) print(“统计摘要:”) print(f” 总密码数: {report[‘summary’][‘total_passwords’]}”) print(f” 非常强: {report[‘summary’][‘very_strong’]}”) print(f” 强: {report[‘summary’][‘strong’]}”) print(f” 中等: {report[‘summary’][‘medium’]}”) print(f” 弱: {report[‘summary’][‘weak’]}”) print(f” 非常弱: {report[‘summary’][‘very_weak’]}”) print(“-“*60) print(“安全建议:”) for i, rec in enumerate(report[‘recommendations’], 1): print(f” {i}. {rec}”) print(“=”*60) def create_sample_config(): “””创建示例配置文件””” sample_config = { “min_length”: 8, “max_length”: 128, “require_uppercase”: True, “require_lowercase”: True, “require_digits”: True, “require_special_chars”: True, “min_special_chars”: 1, “blacklist_words”: [ “password”, “123456”, “qwerty”, “admin”, “welcome”, “login”, “root”, “guest”, “user”, “test”, “abc123” ], “keyboard_patterns”: [ “qwerty”, “asdf”, “zxcv”, “1234”, “abcd”, “qwer” ], “scoring_weights”: { “length”: 0.3, “complexity”: 0.4, “patterns”: 0.2, “entropy”: 0.1 } } with open(‘password_checker_config.json’, ‘w’, encoding=’utf-8′) as f: json.dump(sample_config, f, indent=2, ensure_ascii=False) logger.info(“示例配置文件已创建: password_checker_config.json”) def generate_strong_password(length: int = 16) -> str: “””生成强密码””” alphabet = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()” password = ”.join(secrets.choice(alphabet) for _ in range(length)) return password def main(): parser = argparse.ArgumentParser(description=’密码强度检测器’) parser.add_argument(‘password’, nargs=’?’, help=’要检测的密码’) parser.add_argument(‘-f’, ‘–file’, help=’包含密码列表的文件路径’) parser.add_argument(‘-o’, ‘–output’, help=’输出结果文件路径’) parser.add_argument(‘-c’, ‘–config’, help=’配置文件路径’) parser.add_argument(‘–generate’, type=int, nargs=’?’, const=16, help=’生成指定长度的强密码’) parser.add_argument(‘–sample-config’, action=’store_true’, help=’创建示例配置文件’) parser.add_argument(‘–interactive’, action=’store_true’, help=’交互式检测模式’) args = parser.parse_args() if args.sample_config: create_sample_config() return if args.generate: password = generate_strong_password(args.generate) print(f”生成的强密码: {password}”) return # 加载配置 config = {} if args.config and os.path.exists(args.config): try: with open(args.config, ‘r’, encoding=’utf-8′) as f: config = json.load(f) except Exception as e: logger.error(f”加载配置文件失败: {str(e)}”) # 创建检测器实例 checker = PasswordStrengthChecker(config) try: if args.interactive: # 交互式模式 while True: try: password = input(“n请输入要检测的密码 (输入 ‘quit’ 退出): “) if password.lower() == ‘quit’: break if not password: continue result = checker.evaluate_password_strength(password) checker.print_result(result) except KeyboardInterrupt: print(“n退出交互模式”) break except Exception as e: logger.error(f”密码检测出错: {str(e)}”) elif args.file: # 文件批量检测模式 passwords = checker.load_passwords_from_file(args.file) results = checker.check_password_list(passwords) # 保存结果 output_file = args.output or f”password_check_results_{datetime.now().strftime(‘%Y%m%d_%H%M%S’)}.json” checker.save_results(results, output_file) # 生成报告 report = checker.generate_report(results) report_file = f”{output_file}.report.json” with open(report_file, ‘w’, encoding=’utf-8′) as f: json.dump(report, f, indent=2, ensure_ascii=False) logger.info(f”检测报告已保存到 {report_file}”) # 打印报告 checker.print_report(report) elif args.password: # 单密码检测模式 result = checker.evaluate_password_strength(args.password) checker.print_result(result) # 保存结果 if args.output: checker.save_results([result], args.output) else: # 显示帮助信息 parser.print_help() except KeyboardInterrupt: logger.info(“密码检测被用户中断”) sys.exit(1) except PasswordSecurityError as e: logger.error(f”密码安全错误: {str(e)}”) sys.exit(1) except Exception as e: logger.error(f”密码检测过程中发生未知错误: {str(e)}”) sys.exit(1) if __name__ == ‘__main__’: main()
  • 创建一个名为 config.json 的配置文件: { “min_length”: 12, “max_length”: 128, “require_uppercase”: true, “require_lowercase”: true, “require_digits”: true, “require_special_chars”: true, “min_special_chars”: 2, “blacklist_words”: [ “password”, “123456”, “qwerty”, “admin”, “welcome”, “login”, “root”, “guest”, “user”, “test”, “abc123”, “password123”, “admin123” ], “keyboard_patterns”: [ “qwerty”, “asdf”, “zxcv”, “1234”, “abcd”, “qwer”, “qazwsx”, “plmokn” ], “scoring_weights”: { “length”: 0.25, “complexity”: 0.35, “patterns”: 0.25, “entropy”: 0.15 } }
  • 创建一个名为 passwords.txt 的密码文件: MyPassword123!weakpasswordAdmin123qwerty123StrongPass!@#456testuserSecurePassword2023$password12345678MySecurePass99!
  • 目录
    • 功能介绍
    • 场景应用
      • 1. 系统管理员使用
      • 2. 开发者集成
      • 3. 安全审计
      • 4. 个人用户
    • 报错处理
      • 1. 输入验证异常
      • 2. 文件操作异常
      • 3. 内存安全异常
      • 4. 配置文件异常
    • 代码实现
      • 使用说明
        • 1. 基本使用
        • 2. 批量检测
        • 3. 配置文件使用
      • 配置文件示例
        • 密码文件格式
          • 高级特性
            • 1. 集成到应用程序
            • 2. 定期安全审计
            • 3. 企业级部署
          • 性能优化
            • 1. 内存管理
            • 2. 检测速度优化
            • 3. 错误处理优化
          • 安全考虑
            • 1. 数据安全
            • 2. 系统安全
            • 3. 隐私保护

          这是一个专业的密码强度检测工具,用于评估密码的安全性和强度。该工具具备以下核心功能:

          多维度强度评估

          • 长度检测(密码长度要求)
          • 字符类型检测(大小写字母、数字、特殊字符)
          • 字典攻击防护(常见密码和弱密码检测)
          • 模式识别(键盘序列、重复字符等)
          • 熵值计算(密码随机性评估)

          详细评分系统

          • 综合评分机制(0-100分制)
          • 分项评分展示(长度、复杂度、模式等)
          • 强度等级划分(弱、中、强、 very strong)
          • 改进建议提供

          自定义策略支持

          • 可配置的密码策略
          • 自定义评分权重
          • 特定行业标准支持(如NIST、PCI DSS等)
          • 黑名单词汇库

          批量检测功能

          • 支持批量密码检测
          • 密码文件批量分析
          • 检测结果统计报告
          • 弱密码列表导出

          安全防护机制

          • 内存安全处理(避免密码明文存储)
          • 输入安全验证
          • 防止暴力 破解保护
          • 安全日志记录

          • 检查用户账户密码强度
          • 定期审计系统密码安全性
          • 识别弱密码账户并强制更换
          • 制定和执行密码策略

          • 集成到用户注册和密码修改流程
          • 实时密码强度提示
          • 密码策略验证
          • 用户体验优化

          • 企业密码安全评估
          • 合规性检查(等保、ISO 27001等)
          • 渗透测试中的密码分析
          • 安全培训和意识提升

          • 检查个人账户密码安全性
          • 创建更强的密码
          • 密码管理器集成
          • 安全意识教育

          try:
              password = input("请输入密码: ")
              if not password:
                  raise PasswordValidationError("密码不能为空")
              if len(password) > MAX_PASSWORD_LENGTH:
                  raise PasswordValidationError(f"密码长度不能超过 {MAX_PASSWORD_LENGTH} 个字符")
          except PasswordValidationError as e:
              logger.error(f"密码输入验证失败: {str(e)}")
              raise PasswordSecurityError(f"输入错误: {str(e)}")
          

          try:
              with open(password_file, 'r', encoding='utf-8') as f:
                  passwords = f.readlines()
          except FileNotFoundError:
              logger.error(f"密码文件不存在: {password_file}")
              raise PasswordSecurityError(f"文件未找到: {password_file}")
          except PermissionError:
              logger.error(f"无权限访问密码文件: {password_file}")
              raise PasswordSecurityError(f"文件访问权限不足: {password_file}")
          

          try:
              # 安全清除密码变量
              password = None
              del password
          except Exception as e:
              logger.warning(f"内存清理失败: {str(e)}")
          

          try:
              with open(config_file, 'r', encoding='utf-8') as f:
                  config = json.load(f)
          except json.JSONDecodeError as e:
              logger.error(f"配置文件格式错误: {str(e)}")
              raise PasswordSecurityError(f"配置文件无效: {str(e)}")
          except FileNotFoundError:
              logger.warning("配置文件不存在,使用默认配置")
              config = DEFAULT_CONFIG
          

          #!/usr/bin/env python3
          # -*- coding: utf-8 -*-
          """
          密码强度检测器
          功能:评估密码的安全性和强度
          作者:Cline
          版本:1.0
          """
          
          import argparse
          import sys
          import json
          import logging
          import os
          import re
          import math
          from datetime import datetime
          from typing import Dict, List, Tuple, Optional
          import hashlib
          import secrets
          
          # 配置日志
          logging.basicConfig(
              level=logging.INFO,
              format='%(asctime)s - %(levelname)s - %(message)s',
              handlers=[
                  logging.FileHandler('password_checker.log'),
                  logging.StreamHandler(sys.stdout)
              ]
          )
          logger = logging.getLogger(__name__)
          
          class PasswordSecurityError(Exception):
              """密码安全异常类"""
              pass
          
          class PasswordValidationError(Exception):
              """密码验证异常类"""
              pass
          
          class PasswordStrengthChecker:
              def __init__(self, config: Dict[str, any] = None):
                  # 默认配置
                  self.default_config = {
                      "min_length": 8,
                      "max_length": 128,
                      "require_uppercase": True,
                      "require_lowercase": True,
                      "require_digits": True,
                      "require_special_chars": True,
                      "min_special_chars": 1,
                      "blacklist_words": [
                          "password", "123456", "qwerty", "admin", "welcome",
                          "login", "root", "guest", "user", "test"
                      ],
                      "keyboard_patterns": [
                          "qwerty", "asdf", "zxcv", "1234", "abcd"
                      ],
                      "scoring_weights": {
                          "length": 0.3,
                          "complexity": 0.4,
                          "patterns": 0.2,
                          "entropy": 0.1
                      }
                  }
                  
                  # 合并配置
                  self.config = {**self.default_config, **(config or {})}
                  
                  # 特殊字符集合
                  self.special_chars = "!@#$%^&*()_+-=[]{}|;:,.<>?"
                  
                  # 检测结果统计
                  self.stats = {
                      "total_checked": 0,
                      "strong_passwords": 0,
                      "medium_passwords": 0,
                      "weak_passwords": 0,
                      "very_weak_passwords": 0
                  }
                  
              def calculate_entropy(self, password: str) -> float:
                  """计算密码熵值"""
                  if not password:
                      return 0.0
                      
                  # 计算字符集大小
                  charset_size = 0
                  if re.search(r'[a-z]', password):
                      charset_size += 26
                  if re.search(r'[A-Z]', password):
                      charset_size += 26
                  if re.search(r'[0-9]', password):
                      charset_size += 10
                  if re.search(r'[^a-zA-Z0-9]', password):
                      charset_size += len(self.special_chars)
                      
                  # 计算熵值
                  if charset_size > 0:
                      entropy = len(password) * math.log2(charset_size)
                      return min(entropy, 100.0)  # 限制最大值
                  return 0.0
                  
              def check_length(self, password: str) -> Tuple[int, str]:
                  """检查密码长度"""
                  length = len(password)
                  min_len = self.config["min_length"]
                  max_len = self.config["max_length"]
                  
                  if length < min_len:
                      return 0, f"密码长度不足,至少需要 {min_len} 个字符"
                  elif length > max_len:
                      return 0, f"密码长度过长,最多允许 {max_len} 个字符"
                  else:
                      # 长度评分(线性增长)
                      score = min(100, (length / max_len) * 100)
                      return int(score), f"密码长度合适 ({length} 个字符)"
                      
              def check_complexity(self, password: str) -> Tuple[int, str]:
                  """检查密码复杂度"""
                  score = 0
                  feedback = []
                  
                  # 检查小写字母
                  if re.search(r'[a-z]', password):
                      score += 25
                  elif self.config["require_lowercase"]:
                      feedback.append("缺少小写字母")
                      
                  # 检查大写字母
                  if re.search(r'[A-Z]', password):
                      score += 25
                  elif self.config["require_uppercase"]:
                      feedback.append("缺少大写字母")
                      
                  # 检查数字
                  if re.search(r'[0-9]', password):
                      score += 25
                  elif self.config["require_digits"]:
                      feedback.append("缺少数字")
                      
                  # 检查特殊字符
                  special_count = len(re.findall(r'[^a-zA-Z0-9]', password))
                  if special_count >= self.config["min_special_chars"]:
                      score += 25
                  elif self.config["require_special_chars"]:
                      feedback.append(f"特殊字符不足,至少需要 {self.config['min_special_chars']} 个")
                      
                  if not feedback:
                      feedback_msg = "字符类型齐全"
                  else:
                      feedback_msg = "、".join(feedback)
                      
                  return score, feedback_msg
                  
              def check_patterns(self, password: str) -> Tuple[int, str]:
                  """检查密码模式"""
                  score = 100
                  feedback = []
                  
                  # 检查黑名单词汇
                  password_lower = password.lower()
                  for word in self.config["blacklist_words"]:
                      if word in password_lower:
                          score -= 30
                          feedback.append(f"包含常见弱密码词汇: {word}")
                          
                  # 检查键盘序列
                  for pattern in self.config["keyboard_patterns"]:
                      if pattern in password_lower or pattern[::-1] in password_lower:
                          score -= 20
                          feedback.append(f"包含键盘序列: {pattern}")
                          
                  # 检查重复字符
                  if re.search(r'(.)1{2,}', password):
                      score -= 15
                      feedback.append("包含过多重复字符")
                      
                  # 检查连续字符
                  consecutive_count = 0
                  for i in range(len(password) - 2):
                      if ord(password[i+1]) == ord(password[i]) + 1 and ord(password[i+2]) == ord(password[i]) + 2:
                          consecutive_count += 1
                  if consecutive_count > 0:
                      score -= 10 * consecutive_count
                      feedback.append(f"包含 {consecutive_count} 组连续字符")
                      
                  # 确保分数不低于0
                  score = max(0, score)
                  
                  if not feedback:
                      feedback_msg = "未发现明显模式问题"
                  else:
                      feedback_msg = "、".join(feedback)
                      
                  return score, feedback_msg
                  
              def evaluate_password_strength(self, password: str) -> Dict[str, any]:
                  """评估密码强度"""
                  if not password:
                      raise PasswordValidationError("密码不能为空")
                      
                  # 基本验证
                  if len(password) > self.config["max_length"]:
                      raise PasswordValidationError(f"密码长度不能超过 {self.config['max_length']} 个字符")
                      
                  # 各项检测
                  length_score, length_feedback = self.check_length(password)
                  complexity_score, complexity_feedback = self.check_complexity(password)
                  patterns_score, patterns_feedback = self.check_patterns(password)
                  entropy_score = self.calculate_entropy(password)
                  
                  # 计算综合得分
                  weights = self.config["scoring_weights"]
                  total_score = (
                      length_score * weights["length"] +
                      complexity_score * weights["complexity"] +
                      patterns_score * weights["patterns"] +
                      entropy_score * weights["entropy"]
                  )
                  
                  # 确定强度等级
                  if total_score >= 80:
                      strength_level = "very_strong"
                      strength_desc = "非常强"
                  elif total_score >= 60:
                      strength_level = "strong"
                      strength_desc = "强"
                  elif total_score >= 40:
                      strength_level = "medium"
                      strength_desc = "中等"
                  else:
                      strength_level = "weak"
                      strength_desc = "弱"
                      
                  # 更新统计
                  self.stats["total_checked"] += 1
                  if strength_level == "very_strong":
                      self.stats["strong_passwords"] += 1
                  elif strength_level == "strong":
                      self.stats["strong_passwords"] += 1
                  elif strength_level == "medium":
                      self.stats["medium_passwords"] += 1
                  else:
                      self.stats["weak_passwords"] += 1
                      
                  result = {
                      "password": self.mask_password(password),
                      "score": round(total_score, 2),
                      "strength_level": strength_level,
                      "strength_description": strength_desc,
                      "details": {
                          "length": {
                              "score": length_score,
                              "feedback": length_feedback
                          },
                          "complexity": {
                              "score": complexity_score,
                              "feedback": complexity_feedback
                          },
                          "patterns": {
                              "score": patterns_score,
                              "feedback": patterns_feedback
                          },
                          "entropy": {
                              "score": round(entropy_score, 2),
                              "bits": round(math.log2(len(password) or 1), 2) if password else 0
                          }
                      },
                      "recommendations": self.generate_recommendations(
                          length_score, complexity_score, patterns_score
                      ),
                      "timestamp": datetime.now().isoformat()
                  }
                  
                  return result
                  
              def mask_password(self, password: str) -> str:
                  """掩码密码显示"""
                  if len(password) <= 4:
                      return "*" * len(password)
                  else:
                      return password[:2] + "*" * (len(password) - 4) + password[-2:]
                      
              def generate_recommendations(self, length_score: int, complexity_score: int, patterns_score: int) -> List[str]:
                  """生成改进建议"""
                  recommendations = []
                  
                  if length_score < 80:
                      recommendations.append("增加密码长度,建议至少12个字符")
                      
                  if complexity_score < 80:
                      recommendations.append("使用更多类型的字符(大小写字母、数字、特殊符号)")
                      
                  if patterns_score < 80:
                      recommendations.append("避免使用常见词汇、键盘序列和重复字符")
                      
                  if not recommendations:
                      recommendations.append("密码强度良好,继续保持")
                      
                  return recommendations
                  
              def check_password_list(self, passwords: List[str]) -> List[Dict[str, any]]:
                  """批量检查密码列表"""
                  results = []
                  
                  for i, password in enumerate(passwords):
                      try:
                          result = self.evaluate_password_strength(password.strip())
                          results.append(result)
                          logger.info(f"已检查第 {i+1} 个密码")
                      except Exception as e:
                          logger.error(f"检查第 {i+1} 个密码时出错: {str(e)}")
                          results.append({
                              "password": self.mask_password(password.strip()),
                              "error": str(e),
                              "timestamp": datetime.now().isoformat()
                          })
                          
                  return results
                  
              def load_passwords_from_file(self, file_path: str) -> List[str]:
                  """从文件加载密码列表"""
                  try:
                      with open(file_path, 'r', encoding='utf-8') as f:
                          passwords = [line.strip() for line in f if line.strip()]
                      logger.info(f"从文件加载了 {len(passwords)} 个密码")
                      return passwords
                  except FileNotFoundError:
                      logger.error(f"密码文件不存在: {file_path}")
                      raise PasswordSecurityError(f"文件未找到: {file_path}")
                  except Exception as e:
                      logger.error(f"加载密码文件时出错: {str(e)}")
                      raise PasswordSecurityError(f"文件加载失败: {str(e)}")
                      
              def save_results(self, results: List[Dict[str, any]], output_file: str):
                  """保存检测结果"""
                  try:
                      # 确保输出目录存在
                      output_dir = os.path.dirname(output_file) if os.path.dirname(output_file) else '.'
                      os.makedirs(output_dir, exist_ok=True)
                      
                      with open(output_file, 'w', encoding='utf-8') as f:
                          json.dump(results, f, indent=2, ensure_ascii=False)
                          
                      logger.info(f"检测结果已保存到 {output_file}")
                  except Exception as e:
                      logger.error(f"保存检测结果时出错: {str(e)}")
                      raise PasswordSecurityError(f"结果保存失败: {str(e)}")
                      
              def generate_report(self, results: List[Dict[str, any]]) -> Dict[str, any]:
                  """生成检测报告"""
                  weak_passwords = [r for r in results if r.get("strength_level") in ["weak", "very_weak"]]
                  medium_passwords = [r for r in results if r.get("strength_level") == "medium"]
                  strong_passwords = [r for r in results if r.get("strength_level") in ["strong", "very_strong"]]
                  
                  report = {
                      "summary": {
                          "total_passwords": len(results),
                          "very_strong": len([r for r in results if r.get("strength_level") == "very_strong"]),
                          "strong": len([r for r in results if r.get("strength_level") == "strong"]),
                          "medium": len(medium_passwords),
                          "weak": len([r for r in results if r.get("strength_level") == "weak"]),
                          "very_weak": len([r for r in results if r.get("strength_level") == "very_weak"])
                      },
                      "statistics": self.stats,
                      "weak_passwords": weak_passwords[:10],  # 只显示前10个弱密码
                      "recommendations": [
                          "定期更换密码",
                          "使用密码管理器生成和存储复杂密码",
                          "启用多因素认证",
                          "避免在多个账户使用相同密码"
                      ],
                      "timestamp": datetime.now().isoformat()
                  }
                  
                  return report
                  
              def print_result(self, result: Dict[str, any]):
                  """打印检测结果"""
                  print("n" + "="*60)
                  print("密码强度检测结果")
                  print("="*60)
                  print(f"密码: {result['password']}")
                  print(f"综合得分: {result['score']}/100")
                  print(f"强度等级: {result['strength_description']}")
                  print("-"*60)
                  print("详细分析:")
                  print(f"  长度检测: {result['details']['length']['score']}/100 - {result['details']['length']['feedback']}")
                  print(f"  复杂度检测: {result['details']['complexity']['score']}/100 - {result['details']['complexity']['feedback']}")
                  print(f"  模式检测: {result['details']['patterns']['score']}/100 - {result['details']['patterns']['feedback']}")
                  print(f"  熵值检测: {result['details']['entropy']['score']}/100 ({result['details']['entropy']['bits']} bits)")
                  print("-"*60)
                  print("改进建议:")
                  for i, rec in enumerate(result['recommendations'], 1):
                      print(f"  {i}. {rec}")
                  print("="*60)
                  
              def print_report(self, report: Dict[str, any]):
                  """打印检测报告"""
                  print("n" + "="*60)
                  print("密码强度检测报告")
                  print("="*60)
                  print(f"检测时间: {report['timestamp']}")
                  print("-"*60)
                  print("统计摘要:")
                  print(f"  总密码数: {report['summary']['total_passwords']}")
                  print(f"  非常强: {report['summary']['very_strong']}")
                  print(f"  强: {report['summary']['strong']}")
                  print(f"  中等: {report['summary']['medium']}")
                  print(f"  弱: {report['summary']['weak']}")
                  print(f"  非常弱: {report['summary']['very_weak']}")
                  print("-"*60)
                  print("安全建议:")
                  for i, rec in enumerate(report['recommendations'], 1):
                      print(f"  {i}. {rec}")
                  print("="*60)
          
          def create_sample_config():
              """创建示例配置文件"""
              sample_config = {
                  "min_length": 8,
                  "max_length": 128,
                  "require_uppercase": True,
                  "require_lowercase": True,
                  "require_digits": True,
                  "require_special_chars": True,
                  "min_special_chars": 1,
                  "blacklist_words": [
                      "password", "123456", "qwerty", "admin", "welcome",
                      "login", "root", "guest", "user", "test", "abc123"
                  ],
                  "keyboard_patterns": [
                      "qwerty", "asdf", "zxcv", "1234", "abcd", "qwer"
                  ],
                  "scoring_weights": {
                      "length": 0.3,
                      "complexity": 0.4,
                      "patterns": 0.2,
                      "entropy": 0.1
                  }
              }
              
              with open('password_checker_config.json', 'w', encoding='utf-8') as f:
                  json.dump(sample_config, f, indent=2, ensure_ascii=False)
              logger.info("示例配置文件已创建: password_checker_config.json")
          
          def generate_strong_password(length: int = 16) -> str:
              """生成强密码"""
              alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()"
              password = ''.join(secrets.choice(alphabet) for _ in range(length))
              return password
          
          def main():
              parser = argparse.ArgumentParser(description='密码强度检测器')
              parser.add_argument('password', nargs='?', help='要检测的密码')
              parser.add_argument('-f', '--file', help='包含密码列表的文件路径')
              parser.add_argument('-o', '--output', help='输出结果文件路径')
              parser.add_argument('-c', '--config', help='配置文件路径')
              parser.add_argument('--generate', type=int, nargs='?', const=16, help='生成指定长度的强密码')
              parser.add_argument('--sample-config', action='store_true', help='创建示例配置文件')
              parser.add_argument('--interactive', action='store_true', help='交互式检测模式')
              
              args = parser.parse_args()
              
              if args.sample_config:
                  create_sample_config()
                  return
                  
              if args.generate:
                  password = generate_strong_password(args.generate)
                  print(f"生成的强密码: {password}")
                  return
                  
              # 加载配置
              config = {}
              if args.config and os.path.exists(args.config):
                  try:
                      with open(args.config, 'r', encoding='utf-8') as f:
                          config = json.load(f)
                  except Exception as e:
                      logger.error(f"加载配置文件失败: {str(e)}")
                      
              # 创建检测器实例
              checker = PasswordStrengthChecker(config)
              
              try:
                  if args.interactive:
                      # 交互式模式
                      while True:
                          try:
                              password = input("n请输入要检测的密码 (输入 'quit' 退出): ")
                              if password.lower() == 'quit':
                                  break
                              if not password:
                                  continue
                                  
                              result = checker.evaluate_password_strength(password)
                              checker.print_result(result)
                          except KeyboardInterrupt:
                              print("n退出交互模式")
                              break
                          except Exception as e:
                              logger.error(f"密码检测出错: {str(e)}")
                              
                  elif args.file:
                      # 文件批量检测模式
                      passwords = checker.load_passwords_from_file(args.file)
                      results = checker.check_password_list(passwords)
                      
                      # 保存结果
                      output_file = args.output or f"password_check_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
                      checker.save_results(results, output_file)
                      
                      # 生成报告
                      report = checker.generate_report(results)
                      report_file = f"{output_file}.report.json"
                      with open(report_file, 'w', encoding='utf-8') as f:
                          json.dump(report, f, indent=2, ensure_ascii=False)
                      logger.info(f"检测报告已保存到 {report_file}")
                      
                      # 打印报告
                      checker.print_report(report)
                      
                  elif args.password:
                      # 单密码检测模式
                      result = checker.evaluate_password_strength(args.password)
                      checker.print_result(result)
                      
                      # 保存结果
                      if args.output:
                          checker.save_results([result], args.output)
                          
                  else:
                      # 显示帮助信息
                      parser.print_help()
                      
              except KeyboardInterrupt:
                  logger.info("密码检测被用户中断")
                  sys.exit(1)
              except PasswordSecurityError as e:
                  logger.error(f"密码安全错误: {str(e)}")
                  sys.exit(1)
              except Exception as e:
                  logger.error(f"密码检测过程中发生未知错误: {str(e)}")
                  sys.exit(1)
          
          if __name__ == '__main__':
              main()
          

          # 检测单个密码
          python password_checker.py "MyPassword123!"
          
          # 交互式检测模式
          python password_checker.py --interactive
          
          # 生成强密码
          python password_checker.py --generate
          python password_checker.py --generate 20  # 指定长度
          

          # 从文件批量检测密码
          python password_checker.py -f passwords.txt
          
          # 指定输出文件
          python password_checker.py -f passwords.txt -o results.json
          

          # 使用自定义配置文件
          python password_checker.py "MyPassword123!" -c config.json
          
          # 创建示例配置文件
          python password_checker.py --sample-config
          

          创建一个名为 config.json 的配置文件:

          {
            "min_length": 12,
            "max_length": 128,
            "require_uppercase": true,
            "require_lowercase": true,
            "require_digits": true,
            "require_special_chars": true,
            "min_special_chars": 2,
            "blacklist_words": [
              "password", "123456", "qwerty", "admin", "welcome",
              "login", "root", "guest", "user", "test", "abc123",
              "password123", "admin123"
            ],
            "keyboard_patterns": [
              "qwerty", "asdf", "zxcv", "1234", "abcd", "qwer",
              "qazwsx", "plmokn"
            ],
            "scoring_weights": {
              "length": 0.25,
              "complexity": 0.35,
              "patterns": 0.25,
              "entropy": 0.15
            }
          }
          

          创建一个名为 passwords.txt 的密码文件:

          MyPassword123!
          weakpassword
          Admin123
          qwerty123
          StrongPass!@#456
          testuser
          SecurePassword2023$
          password
          12345678
          MySecurePass99!

          from password_checker import PasswordStrengthChecker
          
          # 创建检测器实例
          checker = PasswordStrengthChecker()
          
          # 在用户注册时检查密码强度
          def register_user(username, password):
              try:
                  result = checker.evaluate_password_strength(password)
                  if result['strength_level'] in ['weak', 'very_weak']:
                      return False, "密码强度不足,请使用更强的密码"
                  return True, "密码强度合格"
              except Exception as e:
                  return False, str(e)
          

          # 每周日凌晨2点执行密码安全审计
          0 2 * * 0 /usr/bin/python3 /path/to/password_checker.py -f /path/to/user_passwords.txt -o /var/log/password_audit.json

          # 企业级密码策略配置
          enterprise_config = {
              "min_length": 16,
              "require_uppercase": True,
              "require_lowercase": True,
              "require_digits": True,
              "require_special_chars": True,
              "min_special_chars": 3,
              "blacklist_words": ["companyname", "productname"],  # 企业特定词汇
              "scoring_weights": {
                  "length": 0.2,
                  "complexity": 0.4,
                  "patterns": 0.3,
                  "entropy": 0.1
              }
          }
          
          checker = PasswordStrengthChecker(enterprise_config)
          

          • 安全清除密码变量避免内存残留
          • 批量处理时分批加载避免内存溢出
          • 使用生成器处理大数据集

          • 预编译正则表达式提高匹配速度
          • 缓存常见计算结果
          • 并行处理多个密码检测

          • 实现优雅的错误恢复机制
          • 记录详细的检测日志便于问题追踪
          • 提供友好的错误提示信息

          • 密码在内存中安全处理,避免明文存储
          • 输出结果中密码被适当掩码
          • 配置文件权限合理设置

          • 限制处理密码的数量和大小
          • 实现处理超时机制
          • 记录所有操作日志便于审计

          • 不收集用户密码信息
          • 本地处理不上传任何数据
          • 符合隐私保护法规要求

          这个密码强度检测器是一个功能强大、安全可靠的安全工具,能够帮助用户和企业评估密码的安全性,提升整体网络安全水平。

          以上就是基于Python实现一个专业的密码强度检测器的详细内容,更多关于Python密码强度检测器的资料请关注风君子博客其它相关文章!

          您可能感兴趣的文章:

          • 基于python实现弱密码检测工具
          • Python实现Telnet自动连接检测密码的示例
          • Python实现的密码强度检测器示例
          • 菜鸟使用python实现正则检测密码合法性
          • python使用正则表达式检测密码强度源码分享

          站内搜索