序言
本文基于Python的gmpy2库对RSA算法案进行实现。实现涉及多种数论算法,本文旨在介绍RSA算法的实现流程,不会对于每一个涉及的算法进行深入介绍,而是直接调用gmpy2库的API,有兴趣深入了解的可以参考本博客的其它文章。
gmpy2安装
pip install gmpy2==2.1.0a1
为什么偏偏是2.1.0a1这个版本呢?因为截止到本文最近一次编辑,gmpy2的其它版本依然没有Python 3.5及以上版本的wheel包,pip安装需要下载源代码到本地编译,会造成不必要的麻烦(比如在Windows下会要求你先安装Visual Studio 2015)。
RSA算法实现
RSA算法大体可以分为三个部分:
- 生成密钥对
- 加密
- 解密
生成密钥对
其中生成密钥对包括以下步骤:
- 随机生成两个足够大的素数 p , q p,q p,q
- 计算公共模数 n = p q n=pq n=pq
- 计算欧拉函数 φ ( n ) = ( p − 1 ) ( q − 1 ) φ(n)=(p−1)(q−1) φ(n)=(p−1)(q−1)
- 选取一较小的与φ(n)互质的正整数e作为公共指数。则数对 ( n , e ) (n, e) (n,e)为密钥对中的公钥
- 计算 d = e − 1 m o d    φ ( n ) d=e^{-1}\mod φ(n) d=e−1modφ(n),则数对 ( n , d ) (n, d) (n,d)为密钥对中的私钥
第一步,随机素数生成
根据著名的素数定理,我们可以知道,随机选取一个正整数n,它是素数的概率为 1 l n ( n ) 1\over ln(n) ln(n)1,这个概率并不算小,所以我们用最暴力的方法选取素数:随机选取一个很大的正整数,检测它是否为素数,如果它不是素数,那我们就可以逐个测试它邻近的奇数,直到找到一个素数为止。
比如,我们需要生成一个长度为1024位的素数,那我们先随机选取一个长度为1024位的正整数,它是素数的概率约为 1 l n ( 2 1024 ) ≈ 1 710 {1 \over ln(2 ^{1024})} ≈ {1 \over 710} ln(21024)1≈7101,排除掉偶数,选中素数的概率约为三百五十分之一。
这样问题就转移到如何测试一个正整数是否为素数上了。目前最常用的概率性素性检测方法是米勒-拉宾素性检测法,该算法的原理可以参考本博客的另一篇文章,这里我们使用gmpy2中的素数检测函数。
代码实现:
import gmpy2
from gmpy2 import mpz
rs = gmpy2.random_state()
def gen_prime():
p = gmpy2.mpz_urandomb(rs, 1024)
while not gmpy2.is_prime(p):
p = gmpy2.add(p, 1)
return p
p = gen_pr