系列四:RSA加密
一、基本背景
RSA算法是是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年一起提出的,算法的名字就是三人名字首字母拼凑而成的。
RSA是目前应用最为广泛的非对称加密算法之一,这里延伸一下,所谓的非对称加密,通俗来讲就是数据加密和解密用的不是同一个秘钥。维基百科官方解释如下:
公开密钥密码学(英语:Public-key cryptography)也称非对称式密码学(英语:Asymmetric cryptography)是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;公钥用作加密,私钥则用作解密。使用公钥把明文加密后所得的密文,只能用相对应的私钥才能解密并得到原本的明文,最初用来加密的公钥不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密;不同于加密和解密都使用同一个密钥的对称加密。公钥可以公开,可任意向外发布;私钥不可以公开,必须由用户自行严格秘密保管,绝不透过任何途径向任何人提供,也不会透露给被信任的要通信的另一方。
下图很生动的说明了非对称加密的过程,原文经过公钥加密后,生成密文,而密文的解密只能用私钥完成。而正是因为加密和解密的规则不同,这样就避免了传统加密算法需要传递秘钥可能带来的因秘钥泄露导致不安全问题。
二、算法原理
RSA算法的加密涉及到几个重要的数学概念,包括我们小学学过的质数(又叫素数)、欧拉定理、欧拉函数、模反元素,当然最核心的还是互质关系,在加密过程中会多次用到。
看很多教程里都已Alice和Bob来作为故事的主人公,外国人名字太拗口了,为了方便自己理解记忆,我这里就用小王和小张了。
2.1、生成公钥和私钥
假设小王要给小张用rsa算法发送一条加密信息,他首先生成公钥和私钥,具体包含以下这么几个步骤:
- 随意选择两个不相等的质数
p
和q
,小王选的是3和11(实际应用中,两个数越大越安全); - 计算
p
和q
的乘积 ,n=p
*q
,n为33,这里的n就是秘钥的长度,33转换成二进制是100001,长度是6位,所以秘钥长度是6位;(注:实际应用中,RSA密钥一般是1024位,重要场合则为2048位。) - 计算n的欧拉函数φ(n),把33带入欧拉函数计算结果为20:
φ(n) = φ(p * q) = φ( p)* φ(q) =(p-1) * (q-1)
φ(33) = φ(3 * 11) = φ(3) * φ(11) =(3-1) * (11-1)=20 - 随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质,小王在1到20之间选了7;
- 计算e对于φ(n)的模反元素d,ed ≡ 1 (mod φ(n)),这个公式的意思就是找到整数d,使得ed被φ(n)除的余数为1。设ed是φ(n)的k的整数倍,余数为1,上式等价于:
7 * d = 20k + 1,即7d -20k = 1,也就是一个二元一次方程,该公式可以用扩展欧几里得方法进行求解,这里因为数字比较小,所一眼就能看出来d=3,k=1; - 至此,所有计算就完成,将n和e封装成公钥,n和d封装成私钥,即加密公钥为(33,7),私钥为(33,3)。
2.2、加密消息
生成公钥和秘钥以后,小王就要开始用公钥对信息进行加密了。假设他要发送的信息是m,注意m必须是一个整数,且小于n。如果m是字符串的话,就需要使用事先与小张约好的格式将m转换为一个小于n的非负整数 ,通常取字符串的ascii值或unicode值。
加密的过程其实就是算出下式中的c:
小王设定的m是数字2,那加密结果就是2的7次方除以33的余数,也就是29,然后小王把29发送给了小张。
2.3、解密消息
小张收到小王的加密信息后,就用自己的私钥(33,3)进行解密,解密公式如下:
可以得出,29的3次方除以33的余数一定为2,因此小张就得出了加密前的原文是数字2。
三、Python实现RSA算法
目前有很多库支持实现RSA加密,这里介绍两个比较常见的库:pycryptodome
和rsa
3.1、基于pycryptodome库实现RSA加解密
安装对应的库:
pip install pycryptod