Python实现RSA
前言
密码学作业之RSA
简介
RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
原理
RSA 算法的可靠性基础:对极大整数做因数分解是很困难的。
RSA 是非对称算法,加解密使用不同的密钥。
两个密钥都可以用于加密,解密时需要使用另一个密钥。但是,通常用公钥加密私钥解密,因为公钥是近乎完全公开的,对于私钥加密的数据,有太多的人可以解密了。理论上 A 和 B 之间要通过 RSA 实现保密通信,需要 A 和 B 各自生成一组密钥,同时保管好自己的私钥;用对方的公钥加密要发送的消息,用自己的私钥解密对方发送过来的消息。
加密公式:
c=me mod n
解密公式:
m=cd mod n
加密过程:
(1) 获得接收方公钥(e,n)
(2) 把消息m分组为长度为L的消息分组
(3) 使用上面加密算法计算出密文
(4) 将密文c发送给接收方
解密过程:
(1) 接收方收到明文c
(2) 使用私钥d和上面的解密算法逐一恢复明文分组
(3) 得到明文消息m
生成公钥和私钥:
(1)随意选择两个大的质数 p 和 q,p 不等于 q,计算 N=pq。
(2)根据欧拉函数,求得 r=φ(N)=φ(p)φ(q)=(p−1)(q−1)
(3)选择一个小于 r 的整数 e,使 e 与 r 互质。并求得 e 关于 r 的模反元素,命名为 d(求 d 令 ed≡1(modr))。(模反元素存在,当且仅当 e 与 r 互质)
将 p 和 q 的记录销毁
(N,e) 是公钥, (N,d)(N,d) 是私钥。公钥发送给所有的通信对象(对服务器来说就是所有的客户端),私钥则必须保管好,防止泄露。
核心代码
扩展欧几里得算法求模反元素
1 | def ex_euclid(a, b, list): |
求模反元素
1 | def mod_inverse(a, b): |
快速幂模运算,把b拆分为二进制,遍历b的二进制,当二进制位为0时不计入计算
1 | def quick_pow_mod(a, b, c): |
Miller-Rabin素性检验算法,检验8次
1 | def prime_test_miller_rabin(p, k): |
判断 num 是否与 prime_arr 中的每一个数都互质
1 | def prime_each(num, prime_arr): |
正确性分析ϕ(n)=(p−1)(q−1)
成立的正确性,ϕ(n)表示小于n且与n互质数的个数则小于等于n且与n非互质的数的个数为,n-ϕ(n) = n - (p-1)*(q-1) = n - (pq-q-p+1) = n-n+p+q-1 = p+q-1
所以只要证明小于等于n且与n非互质的数的个数为p+q-1即能证明ϕ(n)=(p−1)(q−1) :这点很容易证明,由于n只有两个素因子p,q。则所有与n非互质的数都可以写成p*x
或q*x
,对于p*x
来讲,x的取值范围为1<=x<=q,对q*x
来讲x的取值范围为1<=x<=p,p*x
与q*x
的唯一交集为p*q
,所以结论成立。
合理性分析
RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。今天只有短的RSA钥匙才可能被强力方式解破。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
但是RSA还是有缺陷的:
(1)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。
(2)安全性,RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价,而且密码学界多数人士倾向于因子分解不是NP问题。
(3)速度太慢,由于RSA 的分组长度太大,为保证安全性,n 至少也要 600 bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。
安全性分析
RSA的安全性依赖于大数分解,这样攻击RSA系统的难度就是大整数因子分解的难度,一般认为这是一个NPC问题,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。 RSA 的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。人们已能分解多个十进制位的大素数。因此,模数n必须选大一些,因具体适用情况而定。
攻击方法:
(1) 共模攻击
(2) 分析RSA锁结构
(3) 素因子的分解
若用1台1 s能进行1亿次因子分解的高速计算机来计算,分解十进制长度为200位的n,其所需时间为3 800 000年.由此可见,对于RSA系统,如果用一个长度为200位(十进制)的n,认为它是比较安全的,如果n的长度更长,因子分解越困难,一般来说,每增加10位二进制数,分解的时间就要加长1倍.密码就越难以破译,加密强度就越高
代码
1 | #coding:utf-8 |