密码学课程设计之公钥密码
公钥密码 又称为非对称密码,拥有公钥密码的用户分别拥有加密密钥和解密密钥。通过加密密钥不能得到解密密钥。并且加密密钥是公开的。

RSA
该算法的数学基础是初等数论中的欧拉定理。
其安全性基于大整数因子分解的困难性。
算法描述
密钥的生成
选择两个大素数 𝑝和𝑞,(𝑝≠𝑞,需要保密,步骤4以后建议销毁)
计算
$$
n=p×q,\varphi(n)=(p-1)×(q-1)
$$选择整数e使
$$
(\varphi(n),e)=1,1<e<\varphi(n)
$$计算d,使
$$
d=e^{-1}mod\varphi(n)
$$
得到:公钥为{e,n};私钥为{d}
加密(用e,n):明文M<n,密文
$$
C=M^e(modn)
$$解密(用d,n):密文C,明文
$$
M=C^d(modn)
$$
密钥的生成
这一步是整个RSA最重要的一步,其安全性就是基于大整数因子分解的困难,所以,选择两个大素数p和q就显得尤为重要!!!
那么,怎么选择呢?
一般的,选取一个素数的过程如下
1 | 随机选一个奇数𝑛(如使用伪随机数产生器) |
Miller-Rabin素数测试算法
费马小定理
设p是一个素数,则对任意整数a,有
$$
a^p{\equiv}a(modp)
$$
二次探测如果p是一个素数,0<x<p,则方程
$$
x^2{\equiv}1(modp)
$$
的解为
$$
x=1或x=p-1
$$
要测试N是否为素数,首先将N−1分解为2sd。在每次测试开始时,先随机选一个介于[1,N−1]的整数a,之后如果对所有的r∈[0,s−1],若ad mod N ≠ 1且a2rd mod N ≠ −1,则N是合数;否则,N有3/4的概率为素数。
增加测试的次数,该数是素数的概率会越来越高。
具体操作:先用randrange()函数生成一个大伪随机数,然后再用Miller-Rabin素数测试算法判断它是不是素数,若是则就用它;不是则再随机生成一个新的伪随机数,再判断,直到找到可以用的大伪随机数p和q。
1 | #Miller_Rabin算法 |
模重复平方计算法
快速求幂运算
1 | def fast_mod(b,n,m): |
公钥e的选择
$$
(\varphi(n),e)=1,1<e<\varphi(n)
$$
在RSA算法中,e和(p-1)*(q-1)互质的条件容易满足,如果选择较小的e,则加、解密的速度加快,也便于存储,但会导致安全问题。
为了减少加密运算时间,很多人采用尽可能小的e值,如3。但是已经证明低指数将会导致安全问题,故此,一般选择e为16位的素数,可以有效防止攻击,又有较快速度。
1 | def E(fn): |
计算私钥d
$$
d=e^{-1}mod\varphi(n)
$$
这里使用扩展欧几里得法求逆元
1 | def D(e,fn): |
加解密
加密
$$
C=M^e(modn)
$$
1 | def RSA_encrypt(e,n,plaintext): |
解密
$$
M=C^d(modn)
$$
1 | def RSA_decrypt(d,n,ciphertext): |
完整代码
1 | import random |
效率分析
由于RSA 的核心算法是模幂运算(大数自乘取模),要提高RSA 算法的效率,首要问题是提高模幂运算的效率。为了找到模幂运算的优化方法,我们不妨先来分析一般的模乘运算(两大数相乘取模),模乘过程中复杂度最高的环节是取模运算,因为一次除法实际上包含了多次加法、减法和乘法,如果在算法中能够尽量减少除法甚至避免除法,则算法的效率会大大提高。
安全性分析
因子分解法
RSA密码体制的安全性主要依赖于整数因子分解问题,试图分解模数n的素因子是攻击RSA最直接的方法。分解方法有试除法、 p−1因子分解法、p+1因子分解法、二次筛因子分解法、椭圆曲线因子分解法、数域筛因子分解法等。但由于因子分解的时间复杂性并没有降为多项式时间,因此,因子分解还是一个计算上的难题,只是需要考虑使用较大的位数,以确保无法在短时间内被破解。
针对参数选择的攻击
共模攻击
多个用户使用相同的模数n,但公、私钥对不同。这种做法是不安全的。同样,不同用户选用的素因子p和q不能相同,因为n是公开的,如果素因子相同,可通过求模数n的公约数的方法得到相同素因子,从而分解模数n。
低指数攻击
为了增强加密的高效性,希望选择较小的加密密钥e。如果相同的消息要送给多个实体,就不应该使用小的加密密钥。同样的,加密密钥d也不能取得太小。
p-1和q-1都应有大的素数因子
攻击防范措施
密钥长度
密钥长度使用至少1024位,现在大部分使用1024*3位
参数选择
- 为避免椭圆曲线因子分解法,p和q的长度相差不能太大
- p和q的差值不应该太小
- gcd(p-1,q-1)应尽量小
- p和q应为强素数