Diffie-Hellman密钥交换算法
隐私计算常用到各种加密算法,那么双方如何协商得到同一个不被泄露的密钥呢?
一种做法是基于RSA,拥有公钥的一方将随机私钥加密提供给对方,对方再利用私钥解密出密钥。于是双方都得到了会话密钥。
上面这种基于非对称加密的方法是SSL 最古老的密钥协商方式,早期的 SSLv2 只支持这种密钥协商机制。
本篇是另一种密钥交换算法,可以保证“通讯双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥”:DH 算法,全称Diffie-Hellman算法。
前置知识
阶
定义 \(a\) 在模 \(m\) 下的阶是同余方程 \(a^x \equiv 1 \mod m\)的最小正整数解,即为 \(\text{ord}_m a\)。
根据欧拉定理,\(a\),\(m\) 互质情况下,上述方程一定有解,其中一个解为 \(\phi(m)\)。 \(\text{ord}_m a\)。一定为 \(\phi(m)\) 的因数。
原根
当 \(\text{ord}_m a=phi(m)\) 时,就称 \(a\) 为模 \(m\) 下的一个原根。
对于原根a,\(a^1, a^2, \cdots, a^{\phi(m)}\) 在模 \(m\) 下各不相同。
正整数有原根的充要条件为:它能表示为下列形式之一: \(2,4,p^n,2p^n\),其中 p 为奇素数。
离散对数
离散对数可以看作模p下指数运算的逆运算。
对于一个整数 b 和素数 p 的一个原根 a ,可以找到惟一的指数 i ,使得 \(b=a^i \mod p\) ,其中 \(0\le i\le p-1\),指数 i 称为 b 的以 a 为基数的模 p 的离散对数,该值被记为 \(\text{ind}_{a,p}(b)\) 。
密钥交换算法
算法原理
1)A、B双方共享两个公开的参数,素数p和整数a,其中a是p的原根。
2)A产生私钥随机数 \(X_A\) (<p),公开 \(Y_A = a^{X_A} \mod p\)
3)B产生私钥随机数 \(X_B\) (<p),公开 \(Y_B = a^{X_B} \mod p\)
4)共享秘密密钥:
-
A: \(K = Y_B ^{X_A} \mod p\)
-
B: \(K = Y_A ^{X_B} \mod p\)
-
可以验证,双方交换一个相同的秘密密钥 K
\[Y_B ^{X_A} = a^{X_A X_B}= Y_A^{X_B} \mod p \]
安全性
敌对方可以利用的参数只有 \(a, p, Y_A, Y_B\),要获取得到私钥,必须通过计算离散对数来确定密钥。
-
对于A,想求出B的私钥:
\(X_B = \text{ind} _{a,p}(Y_B)\)
-
对于B,想求出A的私钥:
\(X_A = \text{ind} _{a,p}(Y_A)\)
Diffie-Hellman密钥交换算法的安全性依赖于计算离散对数的难度。暴力破解的时间复杂度是 \(O(p)\),而Baby-step Giant-step的时间复杂度是\(O(\sqrt p)\)。这里复杂度实际上是指数增长的,我们设 \(n\) 为素数 \(p\) 的二进制位数,那么目前最优算法破解复杂度为 \(O(2^{n/2})\) 。
Baby-step Giant-step算法
给定素数p导出的有限循环群\(\{g^0, g^1, \cdots, g^q\}\),已知\(a=g^k\mod p\),求k。
- 令 \(m=\sqrt {p−1}\),令 \(k=im+j\),其中 \(i, j \in \{0,1,...,m-1\}\).
- 由于\(a=g^k=g^{im+j}\mod p\), 从而\(g^j=ag^{−im}\mod p\).
- 遍历所有可能的 \(i,j\),找到符合\(g^j=ag^{−im}\mod p\) ,则找到 \(k=im+j\).
- 计算分为两部分
- Giant steps:对所有\(i \in \{1,2,...,m-1\}\),计算\(ag^{−im}(\text{mod } p)\),保存到表格。
- Baby steps:查表,并对所有 \(j \in \{1,2,...,m-1\}\),计算\(g^j(\text{mod } p)\),直到符合条件。
- 时间复杂度: \(\sqrt p\)个步骤计算表格, 平均\(0.5\sqrt p\)个步骤寻找 j,一共是 \(1.5\sqrt p\)个步骤。
这里的根号复杂度算法可以看作的整数分块应用。其中 p-1 为 p的欧拉函数值\(\phi(p)=p-1\),m 为 p-1的二次剩余,即为模意义下的开跟运算。通过分块,将枚举空间长度从线性减少到了根号区间。