对CTF中一些RSA解密方法的总结,都是一些比较容易实现的方法(其实也是对网上脚本的集合),复杂的暂时弄不出来。个人脚本(我只是用不惯网上现有的RSA工具了),脚本是交互式的,输入的数字必须是10进制。
#coding:utf-8
import gmpy2,libnum
from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long
def egcd(a,b):
if a==0:
return(b,0,1)
else:
g,y,x=egcd(b%a,a)
return(g,x-(b // a)*y,y)
def extended_gcd(a, b):
x,y = 0, 1
lastx, lasty = 1, 0
while b:
a, (q, b) = b, divmod(a,b)
x, lastx = lastx-q*x, x
y, lasty = lasty-q*y, y
return (lastx, lasty, a)
def CRT(items):#中国剩余定理
N = 1
for a, n in items:
N *= n
result = 0
for a, n in items:
m = N//n
r, s, d = extended_gcd(n, m)
if d != 1:
N=N//n
continue
result += a*s*m
return result % N, N
def p_q_e():
p=int(input("p="))
q=int(input("q="))
e=int(input("e="))
c=int(input("c="))
phi=(p-1)*(q-1)
n=p*q
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print("明文:",libnum.n2s(m))
def Common_Modulus():
n=int(input("n="))
e1=int(input("e1="))
c1=int(input("c1="))
e2=int(input("e2="))
c2=int(input("c2="))
s=egcd(e1,e2)
s1=s[1]
s2=s[2]
# 求模反元素
if s1<0:
s1 = - s1
c1 = gmpy2.invert(c1,n)
elif s2<0:
s2 = - s2
c2 = gmpy2.invert(c2,n)
m = pow(c1,s1,n)*pow(c2,s2,n)%n
print("明文:",libnum.n2s(m))
def Small_plaintext_e3():
e=int(input("e="))
n=int(input("n="))
c=int(input("c="))
for k in range(200000000):
if gmpy2.iroot(c + n * k, e)[1] == 1:
m=gmpy2.iroot(c + n * k, e)[0]
print("明文:",libnum.n2s(m))
break
def n_e_dp():
n=int(input("n="))
e=int(input("e="))
dp=int(input("dp="))
c=int(input("c="))
for i in range(1,65538):
if (dp*e-1)%i == 0:
if n%(((dp*e-1)//i)+1)==0:
p=((dp*e-1)//i)+1
q=n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)%phi
print(libnum.n2s(pow(c,d,n)))
def N2_equal_P():
n1=int(input("n1="))
n2=int(input("n2="))
e1=int(input("e1="))
e2=int(input("e2="))
c1=int(input("c1="))
c2=int(input("c2="))
p=gmpy2.gcd(n1,n2)
#print(p)
q1=n1//p
q2=n2//p
phi_1=(p-1)*(q1-1)
phi_2=(p-1)*(q2-1)
d1=gmpy2.invert(e1,phi_1)
d2=gmpy2.invert(e2,phi_2)
print("m1:",libnum.n2s(pow(c1,d1,n1)))
print("m2:",libnum.n2s(pow(c2,d2,n2)))
def Prime_3():
p=int(input("p="))
q=int(input("q="))
r=int(input("r="))
e=int(input("e="))
c=int(input("c="))
s=(p-1)*(q-1)*(r-1)
d=(gmpy2.invert(e, s))
n=p*q*r
m=pow(c,d,n)
print("明文:",libnum.n2s(m))
def RSA_File():
public_name = input("请输入公钥文件名(没有直接回车):")
flag_name = input("请输入加密文件名:")
private_name = input("请输入私钥文件名(没有直接回车):")
with open(flag_name,'rb') as f:
c = bytes_to_long(f.read())
if private_name=="":
pass
else:
with open(private_name,'r') as private:
Key = RSA.importKey(private.read())
n,e,d,p,q=Key.n,Key.e,Key.d,Key.p,Key.q
m=pow(c,d,n)
print("明文:",libnum.n2s(m))
return
with open(public_name,'r') as public:
key = RSA.importKey(public.read())
n, e = key.n, key.e
print("n=",n)
print("e=",e)
print("c=",c)
def next_prime():
n=int(input("n="))
e=int(input("e="))
c=int(input("c="))
i = gmpy2.isqrt(n)
p, q = 0, 0
while True:
if n - (i * (n // i)) == 0:
p = i
q = n//i
break
i += 1
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print("明文:",libnum.n2s(m))
def Broadcast():
print('n,e,c由文件导入,请确保格式为[{"c": , "e": , "n":}]')
print("不同组用逗号隔开,如[{},{}]")
file_name=input("请输入文件名:")
with open(file_name,'r') as f:
f=f.read()
sessions=eval(f)
data = []
for session in sessions:
e=session['e']
n=session['n']
msg=session['c']
data = data + [(msg, n)]
print("Please wait, performing CRT")
x, n = CRT(data)
e=session['e']
m=gmpy2.iroot(x,e)[0]
print("明文:",libnum.n2s(m))
if __name__=="__main__":
print("1.已知p,q,e")
print("2.共模攻击")
print("3.小明文攻击,e一般为3")
print("4.已知n,e,dp")
print("5.模不互素,求出共因子p")
print("6.三个素数的RSA")
print("7.读取RSA公钥文件,私钥文件和密文")
print("8.p,q相近")
print("9.低加密指数广播攻击")
x=input("请选择解密方法:")
if x=='1':
p_q_e()
if x=='2':
Common_Modulus()
if x=='3':
Small_plaintext_e3()
if x=='4':
n_e_dp()
if x=='5':
N2_equal_P()
if x=='6':
Prime_3()
if x=='7':
RSA_File()
if x=='8':
next_prime()
if x=='9':
Broadcast()
参考:
https://www.dazhuanlan.com/20...
https://www.freebuf.com/artic...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。