FlowingDev

密码强度,给你讲透:你秘密武器的秘密配方竟是……数学

学习如何使用“熵”来衡量密码强度——这个来自信息论的概念,可以量化密码的不可预测性并估算破解时间。

试用工具: 密码强度

一句话概括

密码强度衡量的是攻击者破解你的秘密需要进行的猜测(或“熵”)的规模,并将这种纯粹的计算量转换为人类可以理解的时间估算。

它解决了什么问题

起初,有了计算机,计算机里有了数据,一切都很好。但接着,其他人也想看那些数据,于是我们发明了密码。早期,事情很简单。root、admin、guest。与其说是为了安全,不如说是基本的访问控制,就像一个带把破锁的文件柜。

然后,互联网横空出世。突然之间,那些计算机不再是锁在某个房间里,而是连接到了地球上所有其他的计算机。那把破锁现在守卫着你数字生活的大门,而攻击者在撬锁方面变得越来越厉害。

首先出现的是暴力破解攻击(brute-force attack):挨个尝试所有可能的组合。‘a’、‘b’、‘c’、……‘aa’、‘ab’、……等等。这招能行,但很慢。于是攻击者变得更聪明了。他们意识到人类既懒惰又可预测。这就导致了字典攻击(dictionary attack):与其尝试 axfsvj,不如试试 password、sunshine 或 123456?这种攻击方式的效果好得惊人。

系统管理员们用策略来反击:“你的密码必须有8个字符长,并包含一个数字和一个大写字母!”而用户们,这些向来‘富有创意’的规则遵守者,则用 Password1、Password2 和永恒的经典 P@$$w0rd1 来回应。这些复杂性规则制造了一种虚假的安全感。

我们需要一个更好的方法来衡量密码的质量。不是通过勾选字符类型的复选框,而是通过测量其真正的、不可预测的随机性。我们需要一种方法来量化“难以猜测”的程度。这就是密码强度的概念——植根于信息论这个数学领域——登场的地方。它提供了一个正式的度量标准——熵(entropy)——来估算一个密码在拥有超级计算机的坚定攻击者的猛攻下能撑多久。

底层工作原理

其核心是,密码强度估算就是一场数字游戏。我们试图计算出攻击者为了找到你那根如针般的密码,需要翻遍多大的一堆干草。

### 熵:那个神奇的数字

衡量密码强度的单位是熵(entropy),用“比特”(bits)来度量。在信息论中,熵是衡量不确定性或随机性的指标。对于密码来说,它量化了你的密码有多么不可预测。

基本公式美得令人发指:

Entropy = log₂(Search Space)

“搜索空间”(Search Space)是在给定规则下所有可能密码的总数。对于一个简单的随机生成密码,搜索空间的计算方式是:

Search Space = N ^ L

其中:

  • N 是字符集(你可以从中挑选符号的池子)中可能字符的数量。
  • L 是密码的长度。

让我们把这个代入主公式:Entropy = log₂(N ^ L),它可以简化为 Entropy = L * log₂(N)。

一些常见的字符集大小(N):

  • 纯数字(0-9):N = 10
  • 小写英文字母(a-z):N = 26
  • 大小写混合英文字母(a-z, A-Z):N = 52
  • 字母数字混合大小写(a-z, A-Z, 0-9):N = 62
  • 完整 ASCII 键盘符号:N ≈ 95

所以,对于一个只使用小写字母的8字符密码,其熵为 8 * log₂(26),大约是 8 * 4.7 = 37.6 比特。

“37.6 比特”究竟是什么意思?每增加一个比特的熵,搜索空间就会翻倍。所以,一个有38比特熵的密码比一个37比特的密码破解难度高一倍。正是这种指数级增长,解释了为什么仅仅增加一两个随机字符就能显著提高强度。

### 从熵到破解时间

比特对计算机来说很棒,但人类是用分钟、年和万古来思考的。为了得到破解时间的估算,我们还需要一个要素:攻击者的猜测速度。

这个速度变化很大。一次在线攻击(online attack)(针对一个实时的登录表单进行猜测)可能会被限制在每秒10次猜测。但一个更现实的场景是离线攻击(offline attack),即攻击者已经窃取了密码哈希(hash)的数据库。借助现代的 GPU,他们每秒可以执行数十亿甚至数万亿次哈希计算。

让我们假设一个强大的攻击者每秒可以进行100亿(10¹⁰)次猜测。保证找到密码所需的猜测次数是 2^Entropy。平均来说,他们在猜到一半时就能找到,所以我们可以这样估算时间:

Crack Time = (2^Entropy / 2) / GuessesPerSecond

看看这事态升级得有多快:

熵 (比特) 总猜测次数 平均破解时间 @ 10¹⁰ H/s 安全等级
30 ~10亿 < 0.1 秒 微不足道
40 ~1万亿 ~1 分钟 非常弱
50 ~1千万亿 ~15 小时 弱
60 ~1百京 ~1.8 年 尚可
70 ~1十垓 ~1800 年 强
80 ~1秭 > 宇宙年龄 非常强

这张表显示了为什么多加几个比特的熵就会带来天壤之别。

### 超越暴力破解:模式问题

简单的 L * log₂(N) 公式有一个巨大的缺陷:它假设每个字符都是完全随机选择的。但人类不是这样工作的。我们使用单词、日期和可预测的替换。P@$$w0rd1 并不是一个由9个 ASCII 字符组成的随机序列。

这就是现代密码强度估算器真正聪明的地方。最好的那些,比如 Dropbox 著名的 zxcvbn 库,不只是计算天真的熵。它们像攻击者一样思考,试图找到构造你密码的“最廉价”的方式。

  1. 分块(Chunking): 它们将密码分解成块。Tr0ub4dor&3! 变成 Tr0ub4dor、&、3、!。
  2. 模式匹配(Pattern Matching): 它们根据多种模式分析每个分块:
    • 字典词汇: troubador 在英文字典里吗?(在)。常见吗?(常见)。
    • 常见替换: Tr0ub4dor 是不是看起来像 troubador 把 o 换成 0,a 换成 4?(是)。
    • 键盘模式: 是不是像 qwerty 或 asdfg 这样的序列?
    • 日期: 看起来像 1999 或 2024 吗?
    • 重复字符: 是不是像 aaaaaa 这样的东西?
  3. 成本分析(Cost Analysis): 它们根据每个分块的模式计算其熵。一个常见的字典词汇的熵远低于一个同样长度的随机字符串。password 的熵不是 8 * log₂(52);它更接近 log₂(20000),因为它是从一个常用密码列表中猜一次。
  4. 求和(Summation): 它们将“最廉价”分块的熵加起来,得到一个现实的、经过实战检验的强度估算。这就是为什么 correct-horse-battery-staple 的得分远高于 Tr0ub4dor&3,尽管后者“看起来”更复杂。

真实世界的故事

### 适得其反的公司策略

一家中型科技公司推出了一项严格的新密码策略:最少10个字符,一个大写字母,一个数字,一个符号。目标是强制推行高熵密码。结果他们得到的是一群创建了像 Summer2024!、Fall2024! 和 Winter2025! 这样密码的员工。一个天真的强度计会给这些密码打出不错的分数。但是,当一名攻击者攻破了一个低级账户并发现了这个模式后,他们根本不需要暴力破解。他们只写了个脚本来尝试每个季节和年份的组合,很快就访问了几十个账户。

教训: 强制的复杂性往往会催生可预测的模式。一个好的强度计应该能检测并惩罚这些常见的方案。

### XKCD ‘Correct Horse Battery Staple’ 的顿悟

网络漫画 XKCD 发表了一幅现已成为传奇的关于密码强度的漫画。它比较了 Tr0ub4dor&3(一个典型的“复杂”密码)和 correct horse battery staple(一个由四个常见但随机的单词组成的密码短语)。Tr0ub4dor&3 对人类来说很难记住,但其混合了替换和模式,使得它的熵可以被计算出来,一个执着的破解者可能几天内就能搞定。然而,那个四词密码短语对人类来说却很容易回忆。假设有一个包含2048个常用词的词典,它的熵是 log₂(2048^4),也就是 4 * 11 = 44 比特的有意义的熵。如果攻击者想按字符暴力破解,他们面对的是一个28个字符的字符串,这是一项不可能完成的任务。

教训: 长度通常是比基于符号的复杂性更强大、更用户友好的防御手段。密码短语是你的好朋友。

### 那个并不“随机”的随机密码

一位开发者被要求创建一个系统,为新用户生成安全的、随机的初始密码。他在一个简单的脚本中使用了他所用语言的默认 random() 函数。密码看起来很棒:j8sL2!kP。但这位开发者没有意识到的是,标准的 random() 函数是一个伪随机数生成器(PRNG),它是用系统时钟时间作为种子的。一名攻击者在获得了其中一个密码及其创建时间戳(例如,从一封电子邮件中)后,就能够推断出种子。然后,他们就可以重新生成在同一时间点附近创建的所有用户的整个“随机”密码序列。

教训: 随机性的来源至关重要。对于任何与安全相关的事情,始终使用密码学安全的伪随机数生成器(CSPRNG),比如浏览器中的 window.crypto.getRandomValues() 或 Linux 上的 /dev/urandom。

常见的错误和陷阱

  • 混淆复杂性与强度。 P@$$w0rd! 看起来复杂,但它是一个全球公认的烂密码。four random words joined 概念上简单,但实践中要强大得多,因为它没有可预测的模式而且长得多。
  • 盲目相信‘绿色进度条’。 网上的许多强度计天真得危险。它们只做一个简单的 长度 * 字符集 计算,而不会检查字典、模式或公开的泄露数据。一个弱评估器给出的“强”评级是个谎言。
  • 忽略离线攻击的风险。 不要根据一个试错三次就锁定的登录表单来衡量你的密码强度。要假设攻击者已经拿到了你的哈希密码,正在他家地下室用一堆 GPU 猛攻。始终为最坏的情况做设计。
  • 重复使用密码。 熵值高达128比特的最牛密码,一旦在另一个网站的数据泄露中被曝光,就变得一文不值。攻击者不会去破解它;他们只会从列表里查一下,然后大摇大摆地走进去。
  • 认为只要是随机的,短一点也没关系。 一个真正随机的、使用所有键盘符号的8字符密码有不错的熵(约53比特)。但“不错”已经今非昔比了。考虑到计算成本的下降,它可能在几周或几个月内被破解。长度能提供一个更舒适的安全边际。

为什么你应该关注它

理解密码强度不仅仅是安全专家的事。

作为一名开发者,如果你在构建任何类型的身份验证系统,你就身处第一线。你应该引导用户走向真正有效的方向:长度和不可预测性,而不是强制执行武断的规则(比如必须包含一个只在周二使用的西里尔字母)。集成一个智能的强度估算器可以提供真正帮助用户的实时反馈,而了解这些原则能让你做出更好的架构决策(比如选择像 Argon2 这样缓慢且昂贵的哈希算法)。

作为一名用户,这些知识将你从一个被动的规则遵守者,转变为一个主动的数据捍卫者。它赋予你直觉,去创造那些对你而言既好记又对他们而言难如登天的秘密。这是你整个数字安全态势的理论基础。

深入了解

理论搞定,动手试试吧——100% 在你的浏览器中运行。

试用工具: 密码强度