RSA的算法: 1.任意选取两个不同的大素数p和q计算乘积n=p$\times$q
利用欧拉函数求出与n互质的数的个数$\varphi$(n)=(p-1)$\times$(q-1)
==欧拉函数: ==
欧拉函数的定义:
欧拉函数(Euler’s totient function),即为$\phi$(n),是小于 n 且与 n 互质的数的个数
例如$\varphi$(7)=6,因为与7互质的数有1,2,3,4,5,6。所以只要n为素数则$\varphi$(n)=n-1
2.任意选取一个大整数e满足gcd(e,$\phi$(n))=1,整数e用作==加密钥==(1<e<$\phi$(n))
3确定解密钥d,满足(ed) mod $\varphi$(n) = 1,即ed = k $\times$$\varphi$(n) +1,k$\geq$1是一个任意整数
4.公开整数n和e,秘密保存d
5.将明文m加密为密文c的算m法为:
c=m^e^modn
6.将密文c转换为明文m的算法为:
m=c^d^modn
证明: m = c^d^ mod n 因为 c = m^e^ mod n 将其带入: m = (m^e^ mod n)^d^ mod n = m^ed^ mod n 又因为: ed=k×phi_n+1 所以: m=m×m^k×phi_n^ mod n 又因为:m^k×phi_n^ = (m^k^) ^phi_n^
根据费马小定理:如果若存在整数 a , p 且gcd(a,p)=1,即二者互为质数,则有a^(p-1)^≡ 1(mod p)
又因为与n可以整除的数只有(p,q,1,n),而 m^k^ 不可能为其中一个
所以 m^k×phi_n^ mod n =1
所以证明:m=c^d^modn
==已知p,q,e,n.求私钥d。== ==以下是python源代码:==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import gmpy2p =gmpy2.mpz() q =gmpy2.mpz() e =gmpy2.mpz() phi_n= (p - 1 )*(q - 1 ) d = gmpy2.invert(e, phi_n) print ("d is:" )print (d)求私钥d. m=pow (c,d,n)%n from Crypto.Util.number import bytes_to_longfrom Crypto.Util.number import long_to_bytesc= bytes = long_to_bytes(data)print (bytes )(加密黑客的源码)
==RSA共模攻击== 已知c1,c2,e1,e2,n,共模攻击: 即用两个及以上的公钥(n,e)来加密同一条信息m
因为c1=m^e1^mod n,c2=m^e2^mod n
思路:我们求明文m,仿佛就在眼前,却无力回天;我们试着将c1和c2相乘;得到:c1c2=m^e2+e2^mod n
想办法让m的幂次为1则求出m,由此想到欧几里得算法
扩展欧几里得算法:ax1+by1=gcd(a,b)
设e1,e2为素数,则gcd(e1,e2)=1;
所以推导公式为:m=c1^s1^c2^s2^mod n
=m=c1^s1^c2^s2^mod n=m^e1s1^^+^^e2s2^mod n
以下是源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import libnum import gmpy2 n = ... c1 = ... c2 = ... e1 = ... e2 = ... s = gcdext(e1,e2) m = pow (c1,s[1 ],n)*pow (c2,s[2 ],n)%n print (m)hex_m=hex (m) print (hex_m)import binasciimingwen=binascii.unhexlify('666c61677b34396439313037376131616263623134663161396435343663383062653965667d' ) print (mingwen)
==rsa dp,dq泄露== 已知 dp, dq,c,p,q求明文m:
RSA中已知dq,dp,p,q的计算m步骤(dp = d mod (p-1),dq = d mod (q-1)):
(1).计算q模p的逆元 I ;
(2).计算m1 = (c^dp^) mod p;
(3).计算m2 = (c^dq^) mod q;
(4).计算m=( ( ( (m2-m1) $\times$ I) %q )$\times$ p + m1 ) % n
以下是证明:
以下是python源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 import gmpy2dp= ... dq= ... c= ... p= ... q= ... n=q*p m1=pow (c,dp,p) m2=pow (c,dq,q) I=gmpy2.invert(p,q) m=((((m2-m1)*I)%q)*p+m1)%n print (m)
==dp泄露== 关键公式
1.已知n,e,dp
2.dp e= ed mod (p-1)
以下是大哥的笔记:
以下是源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import gmpy2e = ... n = ... dp = ... c = ... for i in range (1 ,e): if (dp*e-1 )%i == 0 : if n%(((dp*e-1 )//i)+1 ) == 0 : p=((dp*e-1 )//i)+1 q=n//(((dp*e-1 )//i)+1 ) phi=(q-1 )*(p-1 ) d=gmpy2.invert(e,phi) m=pow (c,d,n) print (m)
#==给出公钥和密文.enc文件求解明文==
解题步骤:
1.在线Rsa 公私钥分解 Exponent、Modulus,Rsa公私钥指数、系数(模数)分解求e,n
2.然后用factordb.com求p,q的工具求出p,q
3,写脚本解密.enc文件
以下是python源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import gmpy2import rsae=65537 n=86934482296048119190666062003494800588905656017203025617216654058378322103517 p=285960468890451637935629440372639283459 q=304008741604601924494328155975272418463 phin=(q-1 )*(p-1 ) d=gmpy2.invert(e,phin) key=rsa.PrivateKey(n,e,int (d),p,q) with open ("#文件路径" ,"rb+" )as f: f=f.read() print (rsa.decrypt(f,key))
==低加密指数攻击== 题目情况: 当e指数特别小时,
以下是python源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #python3 ## -*- coding: utf-8 -*-# from gmpy2 import iroot import libnum e = . n = ... c = ... k = 0 while 1: res = iroot(c+k*n,e) #c+k*n 开3次方根 能开3次方即可 print(res) #res = (mpz(13040004482819713819817340524563023159919305047824600478799740488797710355579494486728991357), True) if(res[1] == True): print(libnum.n2s(int(res[0]))) #转为字符串 break k=k+1 #b'flag{25df8caf006ee5db94d48144c33b2c3b}'
==共素数攻击== 共用素指数e,不同的n和c
以下是源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 from gmpy2 import gcd,invertfrom libnum import n2se = 65537 n1 = ... c1 = ... n2 = ... c2 = ... q = gcd(n1, n2) p = n1//q r = n2//q print (n2s(pow (c1, int (invert(e, (p-1 ) * (q-1 ))), n1)).decode(), end = "" )print (n2s(pow (c2, int (invert(e, (r - 1 ) * (q - 1 ))), n2)).decode(), end="" )
==维吉尼亚加密和解密== 维吉尼亚加密解密原理:
以下是加密源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def encrypt (message,key ): cipher = '' non_alpha_count = 0 for i in range (len (message)): if message[i].isalpha(): if message[i].islower(): offset = ord (key[(i - non_alpha_count) % len (key)]) - ord ('a' ) cipher += chr ((ord (message[i]) - ord ('a' ) + offset) % 26 + ord ('a' )) else : offset = ord (key[(i - non_alpha_count) % len (key)]) - ord ('a' ) cipher += chr ((ord (message[i]) - ord ('A' ) + offset) % 26 + ord ('A' )) else : cipher += message[i] non_alpha_count += 1 return cipher message='YzBibXZnaHl6X3swUmF6X2d4eG0wdGhrem9fMG9iMG1fdm9rY2N6dF8hcn0=' key='hgame' print (encrypt(message,key))
以下是解密源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def decrypt (cipher,key ): message = '' non_alpha_count = 0 for i in range (len (cipher)): if cipher[i].isalpha(): if cipher[i].islower(): offset = ord (key[(i - non_alpha_count) % len (key)]) - ord ('a' ) message += chr ((ord (cipher[i]) - ord ('a' ) - offset) % 26 + ord ('a' )) else : offset = ord (key[(i - non_alpha_count) % len (key)]) - ord ('a' ) message += chr ((ord (cipher[i]) - ord ('A' ) - offset) % 26 + ord ('A' )) else : message += cipher[i] non_alpha_count += 1 return message cipher="FfBufEFnmLs6D3siYtL6X2p4iN0cdSlykm9rQN9oMS1jks9rK2R6kL8hor0=" key="hgame" print (decrypt(cipher,key))