RSA介绍及python的应用
这是博主第一次写博客,制作不易,希望三连支持一下,不足之处欢迎提出,我也会加以改进。
文中提到的迪菲赫尔曼加密和一些群论的知识有时间会在下次单独写,虽然不知道下次啥时候…课程繁忙,课内知识学不懂。
RSA简介
RSA基本
历史
RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
原理
RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,即非对称加密方法。非对称加密方法,简单来说,就是加密密钥和解密密钥不同。其中加密密钥又称为公开密钥,解密密钥称为私有密钥。任何人都可以利用某人的加密密钥对明文进行加密成密文,同时这个人可以利用自己的私钥进行解密(私钥必须要隐藏)。
非对称加密大多基于数学上难解的单向函数问题。所谓单向陷门函数,就是通过已知条件可以轻易地计算出结果;而反过来,通过结果反向计算出初始条件十分困难,同时在知道部分条件时反向计算也会变得简单。
RSA就是基于大数的难以进行质因数分解的特性。根据数论,寻找两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
描述
RSA的前身是迪菲赫尔曼加密。迪菲赫尔曼是一次一密的加密方式,也就是加密一次信息需要一个不同的密钥。若是某人A需要与多个人进行信息加密的交换,那么A需要准备多个密钥,显然很不方便。于是人们发明出了RSA算法,这种算法大大简化了上述例子中A的不方便。
举个形象的例子,在RSA中,就相当于A有一保险箱和对应的钥匙。如果B要将明文加密给A,那么A先用钥匙把保险箱打开并把开着的保险箱给B,B将其明文放入保险箱并关闭后给A。因为只有A才有钥匙,所以B将锁着的明文即密文发送给A是安全的,这样A再用其钥匙打开即可获得明文。这样A就可以用一保险箱和钥匙与多人进行信息交换。
步骤(现在B要将明文加密发送给A)
1)选取两个(位数相等)的大素数记为p,q(通过计算机生成,大部分情况下位数是相等的)。
注:现在大约需要使两个素数位数大于150才能保证安全性。(否则当攻击者知道n=p*q中n的值时,可以将p和q的值爆破)
2)计算n=p*q和φ(n)[1]=(p-1)*(q-1)
3)建立乘法群GF(n)[2],选取生成元e[3] 。
4)选取合适的正整数k,得到整数d使d*e=k*φ(n)+1。
5)A将n和e的值发送给B,作为A的公钥;同时A选取的大素数p和q以及计算得到的整数d的值需要保密,其中d为A的私钥。
6)B得到n和e的值,计算密文c=me mod n,并将密文c发送给A.
7)A得到c后,计算得出原来的明文m=cd mod n.
上述步骤中[1][2][3]属于数学中群论的知识,这里不一一阐述。
例子
图二中B将明文加密发送给A,C为攻击者,能够截取A和B传送的信息。C能截取的A和B的信息是e,c和n的值,通过这三个数难以逆推出明文m。(这里的难以推出明文指的是当选取的p和q的位数为150位以上时,下面的例子为了方便计算和理解取p和q分别为53和59)
RSA的单向陷门函数
如图一所示,知道m,e和n的值时候,能较快计算出c;而当知道e,n和c的值的时候,很难通过逆推解出m的值,同时如果知道群n中生成元e的逆元d,也就是A的私钥,也可以较快解出m的值。这就是RSA中的单向陷门函数。
用第三方python库计算简单RSA
运用gmpy2库计算简单的RSA问题
pip install gmpy2 # 安装gmpy2库
常用gmpy2库中的函数
import gmpy2
gmpy2.mpz(n)#初始化一个大整数
gmpy2.mpfr(x)# 初始化一个高精度浮点数x
d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
C = gmpy2.powmod(M,e,n)# 幂取模,结果是 C = (M^e) mod n
gmpy2.is_prime(n) #素性检测
gmpy2.gcd(a,b) #欧几里得算法,最大公约数
gmpy2.gcdext(a,b) #扩展欧几里得算法
gmpy2.iroot(x,n) #x开n次根
上述简单的RSA计算需用到上述代码中求逆元和幂取模的函数。
例子
比如现在我要加密明文ljk,其对应的ASCII码为108106107.(实际中不止ASCII码将字母转化为数字的这一种方式,有多种方式可以将明文转化为数字)。先选取大素数p=51217,q=70207,生成元e=5.
那么可以写出如下python代码:
最后得出的密文是1146743330,也就是我的昵称(我的姓名首字母ljk这种肯定被占用了,只好用RSA加密来取个名字了…)。是不是很有趣,今后自己喜欢的昵称被占用后你也可以尝试用RSA或是其他加密方式将喜欢的昵称转化为密文。
如果想做一下RSA的练习的话,看完这篇文章可以尝试一下BUUCTF中crypto部分的以下题目:RSA,rsarsa.
总结
这篇文章简单地讲述了RSA的原理,加密的步骤以及用python的gmpy2库来计算简单的RSA问题,能实现加密的原因涉及群论的知识,本文并未提及。群论的知识会在下篇文章进行讲解。由于博主知识水平有限,可能部分语言描述不太严谨(群论的知识只是大致知道,对其中的术语可能理解不全),欢迎大佬指出。