您的位置:首页 > 编程语言 > Python开发

Crypto知识相关——RSA算法原理与python实现

2018-01-16 19:16 906 查看
参考了阮一峰的博客,大神就是牛逼啊

RSA加密与解密

RSA加密过程

1. 随机选择两个不相等的质数 p 和 q

e.g 选择两个不想等的质数 p 和 q

# python 实现
import gmpy2
import random
p=gmpy2.mpz(random.randint(1,100000)) #初始化
q=gmpy2.mpz(random.randint(1,100000)) #初始化
gmpy2.is_prime(p) #概率性素性测试
gmpy2.is_prime(q) #概率性素性测试


2. 计算n=p*q

如代码所示,len就是秘钥的长度

n=p*q
len=len(bin(n))-2 #python进制转换的时候会把0b 加上去


3. 计算n的欧拉函数

Euler_n=(p-1)(q-1)


4. 选择一个整数 e ,e大于1小于oula_n,并且e和oula_n互质

e=65537 #通常e 选择 65537
#while(1):
e=random.ranint(1,oula_n)
if (互质):
break


5. 计算e对于oula_n的模反元素d

模反元素可以用扩展欧几里得算法求解

其中 a=e b=Euler_n

def ext_euclid ( a , b ):
if (b == 0):
return 1, 0, a
else:
x , y , q = ext_euclid( b , a % b )
x , y = y, ( x - (a // b) * y )
return x, y, q


计算过程完毕

6. 将n,e封装为公钥,n,d封装为私钥

公钥(n,e);私钥(n,d)

实际应用中,公钥和私钥的数据都采用ASN.1格式表达。

如果相对asn.1有着更深的认识,点击这里

7. 利用公钥加密

对于信息m(字符串取ascii或者unicode,应该是2进制或者10进制?)

利用之前生成的公钥(n,e)加密。其中m必须小于n

#m**e == c % n
#求出其中的C,就是密文
#其中key是(n,e)
def encrypt(m, key):
C, x = key
return (m ** x) % C
#提供简单的方法
pow(m,e,(q*p))


8. 用私钥解密

密文C后,用私钥(n,d)解密,通过下列式子

#c**d == m % n
#其中key是(n,d)
#将key回到到encrypt(m,key)就可以得出
#提供简单的方法
pow(c,d,(p*q))


于是你就可以的到 m了。

9. 如果m>n?

如果要加密大于n的整数,该怎么办?有两种解决方法:一种是把长信息分割成若干段短消息,每段分别加密;另一种是先选择一种”对称性加密算法”(比如DES),用这种算法的密钥加密信息,再用RSA公钥加密DES密钥。

10. 证明可靠性

去看原文博客吧,这里就不写了。

RSA 逆向

RSA中,一共出现了 p,q,n,Euler_n,e,d

六个数字。其中,n,e是公开的公钥,而其他四个不公开。

已知n,e推d

(1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。

(2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。

(3)n=pq。只有将n因数分解,才能算出p和q。

然而,两个质数的成绩是非常难确定的,这也造成了RSA逆向之困难

RSA python实现

当然,如果我们知道 p q n 的话就简单很多了。

python RSA 简单实现 网上看了很多,觉得这个写的最好Python模拟RSA算法

当然,如果做CTF题目的话,我觉得这个代码可以借鉴一下。PYTHON实现RSA的简洁代码

自己动手写 rsa 加密和解密

if __name__ == '__main__':
p = gmpy2.mpz(    )  # 初始化
print gmpy2.is_prime(p)  # 概率性素性测试
q = gmpy2.mpz(    )  # 初始化
print gmpy2.is_prime(p)  # 概率性素性测试
c = gmpy2.mpz(    ) #c 是加密的字符串
Euler_n = gmpy2.mpz(10000)
e = gmpy2.mpz(65537) #一般都这么长
Euler_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, Euler_n)
print "private key:
4000
"
print d #获取私钥
string = str(pow(c, d, p * q)) #解密字符串
# pow(x,y,z)=x**y%z 今天才发现pow原来有三个参数。。。我在感觉专门是给rsa加密解密的?
f = open("flag.txt", "w")
f.write(string)
f.close()
print pow(pow(c, d, p * q),e,(q*p))
#检查一下,没毛病
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息