6 - 公钥加密介绍
公钥加密介绍
原书:《Understanding Cryptography: A Text book for Students and Practitioners》
谁能借我一个能玩明白数论的脑子。
在我们学习公钥加密之前,我们需要介绍数据公钥加密与非对称加密是同一个范畴。
在第一章中介绍过,对称加密至少用了 4000 年了。而公钥加密相较而言,则是十分崭新的产物。在十九世纪七十年代出现。
6.1 对称加密与非对称加密对比
大部分公钥算法基于数论函数。这与对称加密是不同的,对称加密的目标并不是建立输入-输出的精确数学描述。
再看对称加密
在对称加密中,有下面两个特点:
- 加密与解密使用相同的密钥
- 加密与解密函数十分相似
在对称加密中有下面的几个问题:
密钥分发问题
在发送者与接收者之间必须使用一个安全的信息通道建立密钥。需要牢记的是,通讯链路并不是安全的,因此直接在信息通道上发送密钥是不可行的。
密钥数量问题
即便我们解决了密钥分发问题,我们还要处理海量的密钥。如果网络上 \(n\) 个用户的每一对用户都需要一把独有的密钥,那么需要 \(n\cdot (n-1)/2\) 把密钥,每一个用户必须必须保存好 \(n-1\) 把密钥。
不能防止作弊
发送者与接收者具有相同的能力,因为他们拿着同样的密钥。在电子商务应用这,我们需要证实发送者确实发送了特定的信息,比如一个液晶电视网络订单。如果我们仅使用对称加密,发送者后面改变了主意,那么发送者可以声称,接收者一方既供应商生成了这个 "虚假" 的订单。非对称可以实现这种不可抵赖的特性。
非对称加密原则
为了克服上面提到的对称加密中的缺点,Diffie、Hellman 与 Merkle 提出了一个革命性的提议具有下面的特点:加密信息的那位用户不需要令密钥保密。接收者则使用秘密保护的密钥解密密文。为了实现这样的系统,接收者发布一个公钥,所有人都知道这个公钥。接收者持有这个公钥对应的私钥,并使用这个私钥解密。因此接收者密钥 \(k\) 包含两个部分,公钥部分 \(k_{pub}\) 以及私钥部分 \(k_{pr}\)。
此时,我们可以使用公钥加密算法,加密对称加密密钥,比如 AES 密钥。接收者对这一信息解密后,通讯双方就可以进行对称加密通讯了,对称加密比非对称加密更快。
讨论到这里,我们的问题就变成如何构建一个非对称算法。在第七、八与九章中,我们会介绍多个非对称策略。它们都是基于一个通用原则,单向函数,定义如下:
定义 6.1.1 单向函数
如果一个函数 \(f()\) 满足如下条件,那么这个函数是单向函数:
- \(y = f(x)\) 可以轻松计算
- \(x = f^{-1}(y)\) 不可计算
上面提到的 "轻松计算" 与 "不可计算" 并不准确。在数学术语中,我们可以说 \(y = f(x)\) 计算足够快,而 \(x = f^{-1}\) 在已知算法下计算需要极长时间。在公钥策略中,有两个十分流行的单向函数。第一个是整数因数分解问题,这是 RSA 的基石。给定两个大质数,可以轻松计算质数的积。然而,对这个积进行因数分解是十分困难的。另一个常用的单向函数是离散对数问题。
6.2 公钥加密实践
6.2.1 安全性机制
公钥策略不仅能够进行加密数据。主要功能如下列出:
公钥算法主要安全机制:
密钥建立 通过不安全的通道建立密钥,包括 DHKE 与 RSA 密钥传输协议。
不可抵赖 通过数字签名算法,可以提供不可抵赖性与信息完整性
用户验证 我们可以使用挑战-应答机制以及数字签名,来验证用户,比如银行的智能卡
加密 我们可以使用非对称算法进行加密
需要注意的是,对称运算也可以实现加密与用户验证,但是需要在密钥管理上费更多的功夫。非对称运算好像能够实现所有现代安全协议。即便事实却是如此,它主要的缺点在于,它的加密速度真的太慢了,一些块/流运算的加密速度能够达到公钥算法的上百倍甚至上千倍。因此,略为嘲讽地是,在实践中,很少使用公钥加密策略来进行数据加密。不过,在另一方面,对称运算在进行密钥建立以及信息不可抵赖中是有一点问题的。为了利用对称与非对称运算二者的优点,大部分实践中会使用混杂二者的策略。比如 SSL/TLS、IPsec 等网络安全协议。
6.2.2 剩下的问题:公钥认证
我们是如何确定我们拿到的公钥真的来自于某个人呢?实践中,这通常是通过证书实现的。简而言之,证书将公钥绑定到特定实体。
6.2.3 重要的公钥算法
在前面几章中,我们介绍了几种对称加密算法,除此之外,还有上百其他的对称加密算法。但在非对称运算算法中,情况则大不相同。在实践中,只有三种主要的公钥算法家族,可以归为如下几类:
实践中的公钥算法家族
整数因数分解策略 如 RSA
离散对数策略 如DHKE、DSA
椭圆曲线策略 如 ECDH、ECDSA
前两个家族在十九世纪七十年代中期提出,椭圆曲线策略则在十九世纪八十年代中期提出。如果选择何理的密钥长度、参数与操作数,这些策略都极其难以攻击。需要注意的是,这三个家族都可以提供密钥建立、通过数字签名的不可抵赖性以及对数据的加密等特性。
除了上面三个家族,也有基于其他原理提出的公钥策略,但是它们都无法保证对数学攻击的鲁棒性。
6.2.4 密钥长度与安全性层级
所有三个公钥算法家族都基于数论函数。它们需要不同长度的操作数与密钥长度。不出意外,越长的操作数与密钥,算法安全性越高。为了比较不同算法的安全性,引入安全等级这个概念。如果已知攻击需要 \(2^n\) 步,那么可以称算法安全等级为 n 位。这是十分直观的定义,因为拥有安全等级为 n 的对称算法需要 n 位密钥长度。在非对称加密中,运算强度与安全性并不像对称运算中那样直接。下表展示了不同密钥长度下的安全等级。
算法家族 | 运算系统 | 安全等级 80 | 安全等级 128 | 安全等级 192 | 安全等级 256 |
---|---|---|---|---|---|
整数因数分解 | RSA |
1024 位 | 3072 位 | 7680 位 | 15360 位 |
离散对数策略 | DH ,DSA |
1024 位 | 3072 位 | 7680 位 | 15360 位 |
椭圆加密策略 | ECDH ,ECDSA |
160 位 | 256 位 | 384 位 | 512 位 |
对称密钥量级 | AES ,3DES |
80 位 | 128 位 | 192 位 | 256 位 |
长的操作数意味着更长的计算消耗。三个算法家族的计算复杂度在比特长度变化时,计算量将会以立方级增加,比如在 RSA
中进行签名运算,3076 位的计算量将会是 1024 位计算量的 \(3^3\) 倍。在现代计算机中,10 毫秒到 100 毫秒的计算时长是常见的,但是在一些计算量有限的设备如小的 CPU 上,公钥策略性能将会是一个重要的瓶颈。
6.3 公钥算法的数论知识
6.3.1 欧几里得算法
我们以计算最大公除数问题 gcd: greatest common divisor
开始介绍。两个正整数 \(r_0\) 与 \(r_1\) 的 gcd 表示为:
它是同时能整除 \(r_0\) 与 \(r_1\) 的最大除数。比如 \(gcd(21,9) = 3\)。对于比较小的数值,gcd 计算比较简单,可以通过查找各自的因数,进而查找最大的公因数即可。
例 6.1 令 \(r_0 = 84,r_1 = 30\) 有:
gcd 是所有公共质因数的积:
对于在公钥策略中使用的比较大的数值,进行因数分解是比较困难的,计算 gcd 的方法是欧几里得算法。基于下面观测:
我们假设 \(r_0 > r_1\),且二者均为正整数。这个特性可以简单证明,令 \(gcd(r_0,r_1) = g\),因为 \(g\) 可以同时整除 \(r_0\) 与 \(r_1\),有 \(r_0 = g\cdot x\) 以及 \(r_1 = g\cdot y\),其中 \(x > y\),且 \(x\) 与 \(y\) 互质,既,它们没有公因数。另外,\((x-y)\) 与 \(y\) 也互质。且有:
例 6.2 依然令 \(r_0 = 84,r_1 = 30\)
马上,我们可以进行如下的迭代:
只要 \(r_0 -mr_1 > 0\) 即可。如果我们选择最大的 \(m\),那么算法将进行最少的步骤。这是下面的情况:
因为第一项 \((r_0 \quad mod \quad r_1)\) 比第二项 \(r_1\) 更小,我们交换它们的位置:
通过这个过程,我们可以将从两个较大值中寻找 \(gcd\) 的问题,变成在两个较小的值中寻找 \(gcd\) 的问题。这个过程可以进行迭代,直到我们最后得到 \(gcd(r_1,0) -= r_1\)。因为每次迭代都是一个等式,那么最后一次迭代得到的结果就是最初问题的解:
例 6.3 令 \(r_0 = 27,r_1 = 21\)
例 6.4 令 \(r_0 = 973,r_1 = 301\)
现在我们有了欧几里得算法,我们可以给这个算法一个正式的描述:
欧几里得算法
输入:正整数 \(r_0、r_1,r_0 > r_1\)
输出:\(gcd(r_0,r_1)\)
初始化:\(i = 1\)
算法:
注意到,算法在 \(r_i = 0\) 时终止。
6.3.2 扩展欧几里得算法
前面我们看到了寻找两个整数的 \(gcd\) 的方法,欧几里得算法不仅可以用来寻找 \(gcd\)。这个算法的扩展允许我们计算模反,这在公钥运算中十分重要。扩展欧几里得算法 EEA 计算下面形式的线性组合:
其中 \(s\) 与 \(t\) 为整数系数。这个等式通常称作丢番图方程。
问题变成,我们如何计算两个系数 \(s\) 与 \(t\)。算法背后的思想是,我们进行标准的欧几里得算法,但是我们在每一次迭代中将余数 \(r_i\) 用下面的线性组合表示:
如果我们继续这个过程,我们将得到最后的迭代等式:
例 6.5 令 \(r_0 = 973,r_1 = 301\),下面我们在左边计算标准的欧几里得算法,在右侧我们计算系数 \(s_i\) 与 \(t_i\) 满足 \(r_i = s_i r_0 + t_i r_1\):
\(i\) | \(r_{i-2} = q_{i-1}\cdot r_{i-1} + r_i\) | \(r_i = [s_i]r_0 + [t_i]r_1\) |
---|---|---|
\(2\) | \(973 = 3\cdot 301 + 70\) | \(70 = [1]r_0 +[-3]r_1\) |
\(3\) | $301 = 4\cdot 70 + 21 $ | \(21 =301 - 4\cdot 70 = r_1 - 4(1r_0 - 3r_1) = [-4]r_0 + [13]r_1\) |
\(4\) | \(70 = 3\cdot 21 + 7\) | \(7 = 70 - 3\cdot 21 = (1r_0 - 3r_1) - 3(-4r_0 + 13r_1) = [13]r_0 + [-42]r_1\) |
\(21 = 3\cdot 7 + 0\) |
算法计算得到三个参数 \(gcd(937,301) = 7,s = 13,t = -42\),可以一起表示为:
现在我们在每次迭代时得到递归公式,用来计算 \(s_i\) 与 \(r_i\)。假设我们的迭代步为 \(i\),在前两个迭代我们可以计算:
那么在当前的迭代轮 \(i\),我们首先从 \(r_{i-1}\) 与 \(r_{i-2}\) 中计算商 \(q_{i-1}\) 与新的余数 \(r_i\):
等式可被重新写为:
回到我们的目标,将新的余数 \(r_i\) 表示为 \(r_0\) 与 \(r_1\) 的线性组合。我们可以用前面计算的线性组合替换 \(r_{i-2}\) 以及 \(r_{i-1}\) 得到:
对上面的公式进行重新组织,我们可以得到:
上面的公式直接给到我们计算 \(s_i\) 与 \(t_i\) 的公式,\(s_i = s_{i-2} - q_{i-1}s_{i-1}\) 以及 \(t_i = t_{i-2} - q_{i-1}t_{i-1}\),这个递归过程在 \(i \geq 2\) 下成立的。像所有的递归那样,我们需要初始值 \(s_0,s_1,t_0,t_1\),这些初始值可以是 \(s_0 = 1,s_1 = 0,t_0 = 0,t_1 = 1\)。
扩展欧几里得算法 EEA
输入 正整数 \(r_0,r_1,r_0 > r_1\)
输出 \(gcd(r_0,r_1)\),以及 \(s,t\) 使得 \(gcd(r_0,r_1) = s\cdot r_0 + t \cdot r_1\)
初始化 \(s_0 = 1,t_0 = 1,s_1 = 0,t_1 = 1,i = 1\)
算法
就像在前面提到的,EEA 的主要应用是在非对称加密中计算一个整数的模反。我们已经在第一章的仿射运算中遇到过这个问题了,对于仿射运算,我们需要找到密钥 a 模 26 的模反。使用欧几里得算法,这是比较直观的。让我们假设我们希望计算 \(r_1 \quad mod\quad r_0,r_1 < r_0\) 的模反,第一章中已提到过只有在 \(gcd(r_0,r_1) = 1\) 时模反才存在。因此,如果我们应用 EEA,我们得到 \(s\cdot r_0 + t\cdot r_1 = 1 = gcd(r_0,r_1)\),令这个等式模 \(r_0\) 我们得到:
上面的式子中明确定义了 \(r_1\) 的模反:
因此,如果我们需要计算模反 \(a^{-1} \quad mod \quad m\),我们使用 EEA 算法,输入参数为 \(m\) 与 \(a\),输出 \(t\) 就是我们的期望值。
例 6.6 我们的目标是计算 \(12^{-1} \quad mod \quad 67\),12 与 67 互质,既 \(gcd(61,12) = 1\),如果我们使用 EEA,我们得到 \(gcd(67,12) = 1 = s\cdot 67 + t \cdot 12\) 的系数 \(s\) 与 \(t\)。
\(i\) | \(q_{i-1}\) | \(r_i\) | \(s_i\) | \(t_i\) |
---|---|---|---|---|
2 | 5 | 7 | 1 | -5 |
3 | 1 | 5 | -1 | 6 |
4 | 1 | 2 | 2 | -11 |
5 | 2 | 1 | -5 | 28 |
我们得到线性表达:
这样,我们得到 12 的模反:
这一结论可以轻松证明:
我们一般不需要 \(s\) 系数,所以在实践过程中并不会计算这个系数。
EEA 也可以用来计算伽罗瓦域的乘法逆元。这与 AES 算法中的 S 盒以及椭圆曲线的公钥算法有关。EEA 完全可以用来分析多项式。如果我们希望计算一个有限域 \(GF(2^m)\) 的逆,输入给算法的是域元素 \(A(x)\) 以及不可约多项式 \(P(x)\),EEA 计算辅助多项式 \(s(x)\) 与 \(t(x)\),最大公共除数 \(gcd(P(x),A(x))\),有:
因为 \(P(x)\) 是不可约的,\(gcd\) 总等于 1。相似的,有辅助多项式 \(t(x)\) 是 \(A(x)\) 的逆:
例 6.7 我们希望在有限域 \(GF(2^3)\) 中寻找 \(A(x) = x^2\) 的逆,不可约多项式为 \(P(x) = x^3 + x + 1\),\(t(x)\) 的初始值为 \(t_0(x) = 0\),\(t_1(x) = 1\)
迭代 | $r_{i-2}(x) = $ | \([q_{i-1}(x)]r_{i-1}(x) + [r_i(x)]\) | \(t_i(x)\) |
---|---|---|---|
2 | \(x^3 + x + 1\) | \([x]x^2 + [x+1]\) | \(t_2 = t_0 - q_1 t_1 = 0 - x1 \equiv x\) |
3 | \(x^2\) | \([x](x+1) + [x]\) | \(t_3 = t_1 - q_2 t_2 = 1 - x(x) \equiv 1 + x^2\) |
4 | \(x+1\) | \([1]x+[1]\) | \(t_4 = t_2 - q_3 t_3 = x - 1(1 + x^2)\) |
5 | \(x\) | \([x]1 + [0]\) |
最后,可以计算得到逆 \(t_4(x)\):
下面我们检验一下逆关系确实成立,这里我们会用到 \(x^3 \equiv x + 1 \quad mod \quad P(x)\) 以及 \(x^4 \equiv x^2 +x \quad mod \quad P(x)\):
6.3.3 欧拉 Phi 函数
我们现在看另一个在公钥加密系统中使用的工具。我们考虑环 \(Z_m\) 是集合 \({0,1,...,m-1}\)。我们对这个集合中有多少数与 \(m\) 互质感兴趣。这可以使用欧拉 Phi 函数计算:
定义 6.3.1 欧拉 Phi 函数
在 \(Z_m\) 中与 \(m\) 互质的整数数量表示为 \(\phi(m)\)
例 6.8 令 \(m = 6\),集合为 \(Z_6 = \{0,1,2,3,4,5\}\)
在这个集合中,有两个数与 6 互质,那么有 \(\phi(6) = 2\)。
例 6.9 令 \(m = 5\),集合为 \(Z_5 = \{0,1,2,3,4\}\)
在这个集合中,有四个数与 5 互质,那么有 \(\phi(5) = 4\)。
像上面这样简单穷举所有的 \(gcd\) 的方式是低效的。幸运地是,如果我们知道 \(m\) 的因数分解,存在一种关系,可以更加简单计算我们想要的结果。
定理 6.3.1 令 \(m\) 具有下面的规范因数
其中 \(p_i\) 为不同的质数,\(e_i\) 为正整数,那么有:
因为 \(n\) 是不同的质因子的数量,即便 \(m\) 的数值很大,\(n\) 也很小。
例 6.10 令 \(m = 240\),240 的典型因数可以表示为:
这里有三个不同的质因子,可知 \(n = 3\),欧拉 phi 函数有:
这意味着,在 \({0,1,...,239}\) 集合中,有 64 个整数与 \(m = 240\) 互质。
需要注意的是,为了快速计算欧拉 phi 函数,我们需要知道 \(m\) 的因数分解。这在 RSA 算法的核心,如果我们知道某个数的因数分解,我们可以计算欧拉 phi 函数并解密密文,相反,如果我们不知道这个数的因数分解,那么我们不能计算欧拉 phi 函数,且不能解密。
6.3.4 费马小定理以及欧拉定理
下面我们介绍在公钥算法中十分重要的定理。
首先是费马小定理。
定理 6.3.2 费马小定理
令 \(a\) 是一个整数,\(p\) 为一个质数,那么:
算法在有限域 \(GF(p)\) 是模 \(p\) 的,因此,在有限域 \(GF(p)\) 中,定理可以表示为下面的形式:
这个公式在运算中是十分重要的,一个应用是计算一个有限域的逆,我们可以重写等式为 \(a\cdot a^{p-2} \equiv 1\quad (mod \quad p)\),这样,我们马上可以计算得到 \(a\) 对一个质数的模逆:
需要注意的是,上面计算模逆的方法仅在 \(p\) 为质数时有效。
例 6.11 令 \(p = 7,a = 2\),我们可以计算 \(a\) 的逆:
易于证明:
第二个定理是一般化的费马小定理,欧拉定理。
定理 6.3.3 欧拉定理
令 \(a\) 与 \(m\) 为整数,\(gcd(a,m) = 1\),那么:
例 6.12 令 \(m = 12,a = 5\),首先我们计算 \(m\) 的欧拉 phi 函数
现在我们可以校验欧拉定理:
费马小定理是欧拉定理的特例。如果 \(p\) 是一个质数,\(\phi(p) = (p^1 - p^0) = p - 1\),如果我们在欧拉定理中使用这个值,我们可以得到 \(a^{\phi(p)} = a^{p-1}\equiv 1\quad (mod \quad p)\),既费马小定理。