人人都能学编程
English 开始学习
专项 · 网络安全第 4 课 / 共 9 课免费阅读

用数字看暴力破解 · 网络安全入门

猜中一个密码要多久?

课程目录

为什么需要它

「至少一个大写、一个数字、一个符号」这样的密码规则到处都是,但它们不一定让密码更难猜。做一点算术就能看出真正起作用的是什么:这样你既能写出合理的密码检查,也能给自己挑好密码。

直觉理解

想象一把有 3 个转盘的密码锁,每个转盘 10 个数字:10 × 10 × 10 = 1,000 种组合。每多一个转盘,工作量就再乘以 10。

密码也一样。如果每个字符有 size 种可能,密码长 length 位,那就一共有 size ** length 种可能的密码,这叫密钥空间。平均来说,攻击者试到一半就会猜中。

增加长度,是让密钥空间一次又一次地相乘;多加几类符号,只是让每个转盘稍微大一点。所以由普通单词组成的长密码短语,可以胜过一个塞满符号的短密码。

定义

密钥空间 Keyspace

The number of possible passwords: (number of possible characters) to the power of (length).
所有可能密码的数量:(每位可能的字符数)的(长度)次方。

暴力破解 Brute force

Trying every possible password in turn. The average time is keyspace ÷ 2 ÷ guesses per second.
把所有可能的密码挨个试一遍。平均耗时 = 密钥空间 ÷ 2 ÷ 每秒猜测次数。

示例

密钥空间有多大

动手试试

26 个小写字母,或者键盘上 94 个可打印字符。

lower = 26
any_char = 94
print(lower ** 8)
print(any_char ** 8)
print(lower ** 12)
逐步执行
  1. L38 位小写字母:约 2090 亿种。208827064576
  2. L48 位任意字符:每位多了不少,总数多了约 3 万倍。6095689385410816
  3. L512 位小写字母,比 8 位任意字符还多。95428956661682176

换算成天数

动手试试

假设攻击者对一个快速、没加盐的哈希,每秒能猜 100 亿次。这个数只是举例用的假设。

rate = 10_000_000_000
cases = [("8 lowercase", 26, 8), ("8 any", 94, 8), ("16 lowercase", 26, 16)]
for name, size, length in cases:
    seconds = size ** length / 2 / rate
    print(name, round(seconds / 86400, 1), "days")
逐步执行
  1. L1数字里的下划线只是方便阅读:10_000 就是 10000。
  2. L4平均耗时:密钥空间的一半除以速度。
  3. L5一天有 86400 秒。

常见错误

只求复杂,不求长度

P@ssw0rd! 满足所有符号规则,但它出现在每个攻击者的字典里。长度和随机性,比把 a 换成 @ 重要得多。

强密码用在两个地方

一个网站泄露后,攻击者会拿同一个邮箱和密码去其他网站挨个试。用密码管理器,就能让每个网站都有自己的随机密码。

小测验

1. 这段代码会输出什么?

pin_digits = 10
print(pin_digits ** 4)
print(pin_digits ** 6 // pin_digits ** 4)
  1. A
    10000
    100
  2. B
    40
    2
  3. C
    10000
    2
查看答案

答案:A

4 位 PIN 有 10⁴ = 10,000 种可能。多两位,就再乘以 100。

2. 哪个密码的密钥空间更大?

  1. A`Tr0ub4d&`(8 位,每位 94 种可能)
  2. B`correct horse battery staple`(28 位,26 个字母加空格)
查看答案

答案:B

94⁸ 约为 6 × 10¹⁵;27²⁸ 约为 1 × 10⁴⁰。长度以巨大优势取胜(前提是单词是随机选的)。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出读懂规则

    准确写出这段程序的输出。

  2. 改需求更好的密码检查

    problems(pw) 只检查了长度。在长度规则之后,按顺序再加两条规则:

    • 如果密码里一个数字都没有,加上 "no digit"
    • 如果密码转成小写后在 COMMON 里,加上 "common"
  3. 从零写破解需要几天

    写一个函数 crack_days(size, length, rate),返回暴力破解平均需要的天数,保留 1 位小数:

    平均秒数 = size ** length ÷ 2 ÷ rate,一天有 86400 秒。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Keyspace密钥空间The number of possible passwords or keys.
Brute force暴力破解Trying every possible password until one works.
Passphrase密码短语A long password made of several random words.
Password manager密码管理器An app that creates and stores a different random password for every site.