记一道rsa题

crtrsa

来自2021巅峰极客,题目:

from secret import flagn,p,q
#p and q are two primes generated by getPrime
import random
def key_gen():
    while True:
	dp = random.randint(1,1<<20)
	dq = random.randint(1,q-1)
	if gcd(dp, p - 1) == 1 and gcd(dq, q - 1) == 1:
	    d = crt([dp,dq],[p-1,q-1])
	    phi = (p-1)*(q-1)
	    R = Integers(phi)
	    e = R(d)^-1
	    return p*q,e
n,e = key_gen()
print e
print n
print pow(flagn,int(e),n)

'''
e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399
'''

思路:看到dp的范围,1到1<<20,不大,猜测可以爆破,等于dp知道了,接着往已知的公式入手进行推导,得到某个式子与n=p*q联立,取公因数得到p或q。

推导过程:

已知dp\equiv d~mod~(p-1)ed\equiv 1~mod~\phi(n)\Rightarrow ed\equiv 1~mod~(p-1)

将两式子左右相乘,e*dp\equiv 1~mod~(p-1)=1+k(p-1)

再由欧拉定理,若存在gcd(a,x)=1,则有a^{\phi(x)}\equiv 1~mod~x,取x\in (1,p),且与p互素,则x^{\phi(p)}\equiv 1~mod~p\Rightarrow x^{p-1}\equiv 1~mod~p\Rightarrow x^{k(p-1)+1}\equiv x~mod~p(先两侧同时加上k次方,再同时乘上一个x)\Rightarrow x^{e*dp}\equiv x~mod~p=x+kp\Rightarrow x^{e*dp}-x=kp

 综上有x^{e*dp}-x=kpn=p*q,通过两个关系可以得到p,便可以解了。代码如下:

from gmpy2 import *
from Crypto.Util.number import *
import libnum


e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399


x = 1000000001
t0 = pow(x,e,N)#把这部分单独拿循环外头计算,爆破能快一点
for dp in range(1,1<<20+1):
    t = pow(t0,dp,N)-x
    p = gcd(t,N)
    if p != 1:
        print(p)
        #p = 88483113499234291234797595363172914275282163218450540253170700235627922981203
        q = N // p
        try:
            d = invert(e,(p-1)*(q-1))
            m = pow(flag,d,N)
            print(long_to_bytes(m))
        except:
            pass
        break


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值