第 5 天:密码学基础¶
基本术语¶
明文:消息。
密文:被加密的消息。
加密:让明文变成密文。
解密:让密文变成明文。
密码算法:用于加密和解密的数学函数。
密钥:加密或解密所需要的除密码算法之外的关键信息。
数学基础¶
- 整出
- 素数,互素
- gcd
- 模运算,同余
- 逆元
古典密码¶
- 代换密码(substitution):用新的替换原先的内容。
- 置换密码(permutation):打乱原先的顺序。
- Hill 密码
- 其他……
代换密码¶
将明文中的一个字母由其他字母、数字或符号替代的一种方法。
- 凯撒密码
- 仿射密码
- 单表代换
- 多表代换
凯撒密码(Caesar)¶
数学描述:
\(C = E(P) = (P + K) \mod 26\) (C: Cipher, E: Encrypt, P: Plain, K: Key)
\(P = D(C) = (C - K) \mod 26\) (D: Decrypt)
仿射密码(Affine)¶
\(y = E(x) = ax + b \mod n ~ (\gcd(a, n) = 1)\)
\(x = D(y) = a^{-1} (y - b) \mod n\)
单表代换密码¶
密码表是乱的的凯撒密码。
多表代换密码¶
利用多个表进行加解密,比如维吉尼亚密码。
这些密码都没有改变统计规律。对于英文,每个字母的出现频率都是不一样的。
手撕维吉尼亚密码¶
步骤:
- 确定密钥的长度。
- 确定密钥的内容。
- 根据密钥恢复明文。
维吉尼亚密码的密钥是循环重复的。如果我们知道了密钥的长度 m,破解难度就会降低。
将相同字母组找出来,然后求距离差的最大公约数 gcd(),由此猜测 m。
频率排序:
两个字母: th, he, in, er, re, on, an, en
三个字母: the, and, tio, ati, for, tha, ter, res
确定了秘钥长度 m 之后,可以把密文的第 x 个,第 m + x 个,第 2m + x 个……密文字母提取出来组成一个新的文本,这个抽取出来的文本,都是由秘钥的第 一个字符加密得到的,就相当于一个凯撒密码。
然后利用重合指数法爆破它们。
置换密码¶
分组后对每一组中进行一个更换。
栅栏密码¶
把明文分割成 k 行,然后重新拼接。
Hill 密码¶
利用可逆矩阵加密解密。
编码算法¶
编码算法不是加密算法,因为编码本身的过程没有密钥,只是用于将信息用其他形式进行表示的一种方法。
- ASCII & Unicode & UTF-8
- Hex & Bin 表示
- Base64
- 摩斯密码
- 培根密码
Unicode¶
Unicode 为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF。
UTF-8¶
是变长的。
编号范围 | 二进制格式 |
---|---|
0x00 - 0x7f | 0xxxxxxx |
0x80 - 0x7ff | 110xxxxx 10xxxxxx |
0x800 - 0xffff | 1110xxxx 10xxxxxx 10xxxxxx |
0x10000 - 0x10ffff | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Hex & Bin 表示¶
在计算机上的存储方法。比如“abc”的 hex 表示就是 616263,bin 表示就是 01100001 01100010 01100011。
Base64¶
是一种将 byte 数组编码为字符串的方法,而且编码出的字符串只包含 ASCII 基础字符。
隐写术¶
隐写的信息通常用一些传统的方法进行加密,然后用某种方法修改一个“伪装文本”(covertext),使其包含被加密过的消息,形成所谓的“隐秘文本”(stegotext)。例如,文字的大小、间距、字体,或者掩饰文本的其他特性可以被修改来包含隐藏的信息。
流密码¶
利用密钥 k 产生一个密钥流 z = z0z1z2...(长度无限,明文有多长,密钥流就有多长)然后与明文进行 x = x0x1x2... 操作(例如异或),得到密文。
密钥流由密钥流发生器生成,为了保证安全新,使密钥流生成器要有不可预测性,具体表现如下:
- 长周期
- 高线性复杂度
- 统计性能良好
- 足够的“混乱”
- 足够的“扩散”
- 抵抗不同形式的攻击
RC4 算法¶
伪随机生成器¶
- 线性同余生成器(Linear congruential generator,LCG)
- 线性反馈移位寄存器(linear feedback shift register,LFSR)
- MT19937(Python Random 库内部实现)
线性同余生成器(LCG)¶
\(X_{n+1} = (aX_{n} + c) \mod m\)
线性反馈移位寄存器(LFSR)¶
非线性反馈移位寄存器(NLFSR)¶
MT19937¶
- 利用 seed 初始化 624 个 int 构成的状态。
- 对状态进行旋转。
- 根据状态提取伪随机数。
逆向 extract_number¶
y = y ^ y >> 18
:y 的高 18 位没有改变。
y = y ^ y << 15 & 4022730752
:可以推出 y 的低 15 位。
并进一步推出低 30 位以及以后的位数。
像这样一路逆下去就好了。
预测随机数¶
加密时的 key 是第 701 个随机数……用前面 624 个随机数逆出初始的状态!
现代密码¶
- 对称密码:加解密时使用的密钥相同
- 非对称密码:加解密时使用的密钥不相同,分为公钥,私钥。公钥是可以公开的(即 他人可以知道),而私钥需要被保护(只有自己知道)。
对称密码¶
加密和解密采用相同的密钥。
DES¶
是一种对称密码,但是由于计算机的性能提升,这个算法的安全性已经很低了。
- 输入:64 位
- 输出:64 位
- 密钥:64 位中的 56 位
3DES¶
就是 DES 三次。
为什么 2 次不行?考虑 Meet in the middle。
AES¶
- 输入:128 位
- 输出:128 位
- 密钥:128 位,192 位,256 位
非对称密码¶
加解密时使用的密钥不相同,分为公钥,私钥。公钥是可以公开的,而私钥需要被保护。
- RSA
- ECC
RSA¶
欧拉函数,欧拉定理¶
\(\phi(n) =\) 小于等于 n 的正整数中有多少个和 n 互质。
\(a^{\phi(n)} = 1 \mod n,~ \gcd(a, n) = 1\)
公钥和私钥的生成¶
有两个巨大的质数 p,q。
N = pq。\(\phi(N) = \phi(p) \phi(q) = (p-1)(q-1)\)。
找一个 e 让 \(e < \phi(N),~ \gcd(e, \phi(N)) = 1\)。
此时会有 d 让 \(d = e^{-1} \mod \phi(N)\),即 \(de = 1 \mod \phi(N)\)。
把 p 和 q 扫进遗忘的尘埃后,(N, e) 是公钥,(N, d) 是私钥。
对 N 的质因数分解非常困难,也就难以得到 \(\phi(N)\)。即使知道公钥的 e 也基本得不到私钥的 d。
今年寒假我就是靠这个成功转专业的。
加密和解密¶
传递一个小于 N 的整数 m。
\(m^e \equiv c \mod N\)。
传递 c。
\(c^d \equiv m \mod N\)。
正确性?¶
\(\gcd(m, N) \neq 1\):
ECC¶
和椭圆曲线有关。
今天的作业¶
警告
抄袭行为是严厉禁止的。
扩展欧几里得算法¶
这个算法可以求解 \(ax + by = 1\) 的一组 x 和 y(gcd(a, b) = 1)。
\((a, b) = (b, a \bmod b) = (b, a - b \lfloor \frac{a}{b} \rfloor)\)。
如果现在有 x',y' 满足 \(bx' + (a - b \lfloor \frac{a}{b} \rfloor) y' = 1\),就可以用 x',y' 反推出 x,y。
那么此时 \(a(x - y') + b(y - x' + \lfloor \frac{a}{b} \rfloor y') = 0\)。
由于 gcd(a, b) = 1,那么只能让 \(x = y', y = x' - \lfloor \frac{a}{b} \rfloor y'\)。
挑战部分¶
提示
原函数逻辑是这样的:
考虑把这个过程反过来执行。
现在我们有 tmp:tmp 的最右边一位是上次序列与上 mask 后的 1 的奇偶性。
上次序列可以通过这次序列往右移一位得到,但是最左边一位是丢失的。
不过可以找回来。这次序列往右移一位,左边补 0 再与上 mask,如果奇偶性不对的话说明左边应该补一个 1。
逆 208 次就好了。