正在加载,请稍候…

如何生成和评估强密码

了解强密码的构成、密码破解原理、不同场景的密码规则,以及如何在代码中生成安全密码。

如何生成和评估强密码

什么使密码变强?

密码强度归结为一个指标:熵(entropy)——攻击者必须克服的随机性位数。熵越高,需要尝试的组合越多,破解所需时间越长。

公式:

熵(位)= log₂(字符集大小 ^ 密码长度)
        = 密码长度 × log₂(字符集大小)
字符集 大小 12位熵 16位熵
仅数字 10 39.9 位 53.1 位
仅小写字母 26 56.4 位 75.2 位
小写+大写 52 68.4 位 91.2 位
小写+大写+数字 62 71.5 位 95.3 位
小写+大写+数字+符号 94 78.6 位 104.8 位

现代密码破解工具在消费级硬件上:简单哈希约每秒1000亿次尝试。按此速度:

  • 56位熵:约7个月破解
  • 72位熵:约72,000年破解
  • 128位熵:宇宙热寂

实用建议: 对于使用强算法存储的密码,至少128位熵;对于使用MD5/SHA1(攻击者利用泄露数据库进行破解)的情况,目标至少80位熵。

如何生成和评估强密码插图

攻击者如何破解密码

了解攻击方式有助于防御。

字典攻击

攻击者尝试常见单词、姓名、常见替换(a→@, e→3, s→5),并附加常见后缀(123, 2024!, !):

password → P@ssw0rd → P@ssw0rd123 → P@ssw0rd2024!

RockYou、Have I Been Pwned 等词表包含数十亿常见密码及其变体。

掩码攻击(基于模式)

如果攻击者知道密码策略(必须包含大写字母、数字、符号),他们会缩小搜索范围:

掩码: ?u?l?l?l?l?l?d?s → 1个大写 + 5个小写 + 1个数字 + 1个符号

这就是为什么 "Password1!" 很弱——它符合最常见的合规模式。

彩虹表

常见密码的预计算哈希表。通过密码加盐(所有好的密码哈希算法自动执行)来防御。

如何生成和评估强密码插图

什么不起作用(常见误解)

替换(l33tspeak): 攻击者在其字典中包含常见替换。P@ssw0rd 出现在每个词表中。

在末尾添加数字/符号: 攻击者知道用户会这样做。correct1! 并不比 correct1 强多少。

键盘模式: qwertyasdfgh123qwe 都出现在每个词表中。

个人信息: 生日、宠物名、地址——这些是定向攻击中首先被针对的。

什么真正有效

随机字符

一个完全随机的16位密码,使用完整字符集,具有约105位熵,基本上不可破解:

Kp7!mNqX3#rL9sYv

问题:无法记忆。

Diceware 密码短语

一串随机常见单词既高熵又易记:

correct horse battery staple

从7776个单词的词表中选5个单词:log₂(7776^5) = 64.6位。无法通过暴力破解。

6个单词:77.5位。8个单词:103.4位。

在同等熵值下,单词比随机字符更易记。

如何生成和评估强密码插图

密码管理器

实用解决方案:为每个服务生成一个唯一、完全随机的20+字符密码,全部存储在密码管理器中。只需记住一个强主密码。

在代码中生成密码

// 浏览器 / Node.js — 加密安全
function generatePassword(length = 20, options = {}) {
  const {
    uppercase = true,
    lowercase = true,
    digits = true,
    symbols = true,
  } = options;

  let charset = '';
  if (lowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
  if (uppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  if (digits) charset += '0123456789';
  if (symbols) charset += '!@#$%^&*()-_=+[]{}|;:,.<>?';

  if (!charset) throw new Error('At least one character type required');

  const array = new Uint32Array(length);
  crypto.getRandomValues(array);

  return Array.from(array)
    .map(n => charset[n % charset.length])
    .join('');
}

// 使用
const password = generatePassword(24, { symbols: true });
// => "Kp7!mNqX3#rL9sYv2@Hf8qR"
import secrets
import string

def generate_password(length=20, use_symbols=True):
    chars = string.ascii_letters + string.digits
    if use_symbols:
        chars += '!@#$%^&*()-_=+[]{}|;:,.<>?'

    # secrets.choice 使用 os.urandom — 加密安全
    return ''.join(secrets.choice(chars) for _ in range(length))

# Diceware 风格密码短语
import random

WORDLIST = ['apple', 'bridge', 'cloud', ...]  # 加载你的词表

def generate_passphrase(num_words=6):
    return ' '.join(secrets.choice(WORDLIST) for _ in range(num_words))

不同使用场景的密码规则

使用场景 最低要求 推荐 备注
网络账户(bcrypt) 12字符 20+字符 bcrypt 处理工作因子
管理员/特权账户 16字符 30+字符 使用密码短语或密码管理器
Wi-Fi 密码 12字符 20字符 WPA2 无速率限制
PIN(4位数字) 使用6位数字 仅用于低风险、锁定设备
加密密钥密码短语 20字符 Diceware 8个单词 保护加密卷

评估密码强度

一个基于熵的简单评估器:

function estimateEntropy(password) {
  let charset = 0;
  if (/[a-z]/.test(password)) charset += 26;
  if (/[A-Z]/.test(password)) charset += 26;
  if (/[0-9]/.test(password)) charset += 10;
  if (/[^a-zA-Z0-9]/.test(password)) charset += 32;

  const entropy = password.length * Math.log2(charset || 1);

  if (entropy < 40) return { score: 0, label: '非常弱' };
  if (entropy < 56) return { score: 1, label: '弱' };
  if (entropy < 72) return { score: 2, label: '一般' };
  if (entropy < 88) return { score: 3, label: '强' };
  return { score: 4, label: '非常强' };
}

如需更复杂的分析(模式检测、字典检查),请使用 zxcvbn 库,它模拟了真实的攻击模式。

→ 使用 密码强度分析器 测试和分析你的密码强度。