密码安全是一个系统属性,而不是字符数徽章。随机生成的密码仍可能因钓鱼、恶意软件、日志、复用、恢复流程或服务泄露而暴露。本文讨论熵值假设、CSPRNG 无偏采样、密码管理器、MFA 和事件响应,不把任何长度或工具写成安全保证。
目录
核心要点
- 熵值取决于模型:
L × log₂(N)只是均匀独立字符采样的理论上限,不是人类密码的实测值。 - 长度有帮助但并非充分条件:唯一随机密码或独立抽取的词组优于可预测的复杂度模式。
- CSPRNG 还要无偏采样:安全随机源仍可能被取模偏差、日志、剪贴板或复用削弱。
- 避免常见密码:不要使用容易猜测的单词、短语或个人信息
- 使用密码管理器:安全存储和管理所有密码
- 启用多因素认证:为重要账户添加额外的安全层
不要把现有密码粘贴到生成器或“强度检测器”中。只生成新密码,通过可信流程传递,并存储在密码管理器中。
密码安全基础
什么是密码安全?
密码安全是指保护密码免受未授权访问和破解的实践和技术。一个安全的密码应该难以猜测或破解,同时对用户来说易于使用和记忆(或通过密码管理器安全存储)。
常见密码攻击方式
- 暴力破解:尝试所有可能的字符组合
- 字典攻击:使用常见单词、短语和密码列表
- 彩虹表攻击:使用预计算的哈希值表快速查找密码
- 社会工程学:通过欺骗获取密码
- 钓鱼攻击:伪装成可信实体获取密码
- 键盘记录器:记录用户的键盘输入
熵值:密码强度的科学衡量
熵值定义
熵值(Entropy)是衡量密码不确定性的科学指标,通常以比特(bits)为单位。熵值越高,密码越难破解,因为攻击者需要尝试更多的可能组合。
熵值计算公式
熵值的计算公式为:
理论搜索空间(比特) = 密码长度 × log₂(字符集大小)
例如:
- 8位纯小写字母密码:8 × log₂(26) ≈ 8 × 4.7 = 37.6 比特
- 12位混合密码(大小写字母+数字):12 × log₂(62) ≈ 12 × 5.95 = 71.4 比特
- 16位全字符集密码(大小写字母+数字+符号):16 × log₂(94) ≈ 16 × 6.55 = 104.8 比特
不同密码类型的熵值对比
| 密码类型 | 长度 | 字符集大小 | 理论比特数 | 解释 |
|---|---|---|---|---|
| 纯数字 | 6 | 10 | 20 | 搜索空间较小 |
| 纯小写字母 | 8 | 26 | 37.6 | 理论搜索空间 |
| 混合(大小写+数字) | 10 | 62 | 59.5 | 理论搜索空间 |
| 全字符集 | 12 | 94 | 78.6 | 理论搜索空间 |
| 全字符集 | 16 | 94 | 104.8 | 理论搜索空间 |
这些数字假设字符独立且均匀采样,不能直接预测破解时间。攻击成本还取决于在线限速、离线 KDF、硬件、泄露密码列表、密码复用和攻击策略。
密码生成算法详解
随机数生成器
密码生成的核心是使用安全的随机数生成器(RNG):
- 伪随机数生成器(PRNG):使用算法生成看似随机的数,但实际上是确定的
- 密码安全伪随机数生成器(CSPRNG):设计用于密码学应用,提供更高的安全性
- 真随机数生成器(TRNG):使用物理过程生成真正的随机数
密码生成策略
安全密码生成器通常采用以下策略:
- 字符集选择:允许用户选择使用的字符类型(大小写字母、数字、符号)
- 长度控制:允许用户指定密码长度
- 排除相似字符:可选排除容易混淆的字符(如l、1、I、0、O)
- 避免重复字符:可选避免连续重复的字符
- 密码复杂度检查:确保生成的密码满足指定的复杂度要求
常见密码生成模式
- 随机字符模式:完全随机的字符组合
- 记忆化模式:由随机单词和数字符号组合而成(如Diceware方法)
- 自定义模式:允许用户指定密码的结构(如AANNS-AAAA)
密码最佳实践
密码长度与复杂度
- 推荐长度:遵循服务当前的长度策略,优先使用较长且唯一的随机值;密码管理器可以存储更长的值。
- 字符多样性:不要为了满足规则添加可预测替换,使用服务接受的随机字符或词组选择过程。
- 避免常见模式:不要使用"Password123"、"123456"等常见密码
- 基于证据更换:在疑似泄露、服务入侵、恢复流程被攻破或策略变更后轮换;无依据的定期轮换可能制造可预测变体。
密码管理策略
- 使用密码管理器:如Bitwarden、1Password或LastPass
- 唯一密码原则:每个账户使用不同的密码
- 安全存储:不要在不安全的地方(如明文文件、便签)存储密码
- 安全审计:通过密码管理器或服务提供的隐私保护流程检查复用和泄露,不能把现有密码上传到任意检测器。
多因素认证
为重要账户启用多因素认证(MFA),提供额外的安全层:
- 短信验证码:通过短信接收验证码
- 认证应用:如Google Authenticator、Microsoft Authenticator
- 硬件密钥:如YubiKey
- 生物识别:指纹、面部识别等
代码示例
JavaScript
// 使用密码安全的随机数生成器生成密码
function generatePassword(length = 12, options = {
uppercase: true,
lowercase: true,
numbers: true,
symbols: true,
excludeSimilar: false
}) {
if (!Number.isInteger(length) || length <= 0) {
throw new RangeError('长度必须是正整数');
}
const charset = {
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
lowercase: 'abcdefghijklmnopqrstuvwxyz',
numbers: '0123456789',
symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?'
};
let allChars = '';
if (options.uppercase) allChars += charset.uppercase;
if (options.lowercase) allChars += charset.lowercase;
if (options.numbers) allChars += charset.numbers;
if (options.symbols) allChars += charset.symbols;
if (options.excludeSimilar) {
allChars = allChars.replace(/[l1Io0O]/g, '');
}
if (allChars.length === 0) {
throw new Error('至少需要选择一种字符类型');
}
let password = '';
const limit = 256 - (256 % allChars.length);
while (password.length < length) {
const array = new Uint8Array(1);
window.crypto.getRandomValues(array);
if (array[0] >= limit) continue; // 拒绝采样,避免取模偏差
password += allChars[array[0] % allChars.length];
}
return password;
}
// 生成16位包含所有字符类型的密码
const password = generatePassword(16);
// 直接交给可信的密码管理器流程;生产环境不要记录秘密。
Python
import secrets
import string
def generate_password(length=12, uppercase=True, lowercase=True, numbers=True, symbols=True, exclude_similar=False):
charset = ''
if uppercase:
charset += string.ascii_uppercase
if lowercase:
charset += string.ascii_lowercase
if numbers:
charset += string.digits
if symbols:
charset += string.punctuation
if exclude_similar:
charset = charset.translate(str.maketrans('', '', 'l1Io0O'))
if not charset:
raise ValueError("至少需要选择一种字符类型")
password = ''.join(secrets.choice(charset) for _ in range(length))
return password
# 生成14位包含字母和数字的密码
password = generate_password(14, symbols=False)
# 通过可信流程存储;生产环境不要打印秘密。
Java
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;
public class PasswordGenerator {
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String NUMBERS = "0123456789";
private static final String SYMBOLS = "!@#$%^&*()_+-=[]{}|;:,.<>?";
private static final String SIMILAR_CHARS = "l1Io0O";
private final SecureRandom secureRandom;
public PasswordGenerator() {
this.secureRandom = new SecureRandom();
}
public String generate(int length, boolean includeUppercase, boolean includeLowercase,
boolean includeNumbers, boolean includeSymbols, boolean excludeSimilar) {
StringBuilder charset = new StringBuilder();
if (includeUppercase) charset.append(UPPERCASE);
if (includeLowercase) charset.append(LOWERCASE);
if (includeNumbers) charset.append(NUMBERS);
if (includeSymbols) charset.append(SYMBOLS);
String charSetStr = charset.toString();
if (excludeSimilar) {
charSetStr = removeSimilarChars(charSetStr);
}
if (charSetStr.isEmpty()) {
throw new IllegalArgumentException("至少需要选择一种字符类型");
}
StringBuilder password = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int randomIndex = secureRandom.nextInt(charSetStr.length());
password.append(charSetStr.charAt(randomIndex));
}
return password.toString();
}
private String removeSimilarChars(String input) {
Set<Character> similarSet = new HashSet<>();
for (char c : SIMILAR_CHARS.toCharArray()) {
similarSet.add(c);
}
StringBuilder result = new StringBuilder();
for (char c : input.toCharArray()) {
if (!similarSet.contains(c)) {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
PasswordGenerator generator = new PasswordGenerator();
String password = generator.generate(16, true, true, true, true, false);
// 通过可信流程存储;生产环境不要打印秘密。
}
}
常见问题
多长的密码才算安全?
不存在适用于所有服务的安全长度。应遵循服务当前的长度策略,生成唯一随机秘密或独立抽取的口令短语,并同时考虑限速、MFA、恢复流程和泄露风险;密码管理器可以安全保存更长的值。
密码管理器安全吗?
密码管理器可以减少复用和钓鱼风险,但安全性取决于实现、同步/恢复模型、设备安全和主凭据。应选择持续维护的产品,使用唯一强主凭据与 MFA,并了解其泄露、导出和恢复控制。
我应该多久更换一次密码?
在疑似泄露、服务入侵、恢复流程被攻破或策略变更后轮换密码。没有证据的定期轮换可能制造可预测的密码变体。
什么是多因素认证?
多因素认证是一种安全机制,要求用户提供两种或更多种验证因素才能访问账户。常见的因素包括:
- 知识因素:密码或PIN码
- 持有因素:手机或硬件密钥
- 固有因素:指纹或面部识别
总结
密码安全结合唯一生成、安全传递与存储、抗钓鱼机制、MFA、恢复控制、限速和泄露响应。熵值只是生成过程的模型,不是整个账户的安全保证。
快速总结:
- 理论熵值描述的是假设的随机过程
- 优先使用唯一随机秘密或独立抽取的口令短语
- 使用 CSPRNG 和无偏采样,绝不记录生成的秘密
- 为每个账户使用唯一的密码
- 使用密码管理器安全存储和管理密码
- 启用多因素认证以增强安全性
只在可信流程中生成新秘密,避免通过日志或聊天复制,并将其存储在持续维护的密码管理器中。