buu [NPUCTF2020]认清形势,建立信心

题目:

from Crypto.Util.number import *
from gmpy2 import *
from secret import flag

p = getPrime(25)
e = # Hidden
q = getPrime(25)
n = p * q
m = bytes_to_long(flag.strip(b"npuctf{").strip(b"}"))

c = pow(m, e, n)
print(c)
print(pow(2, e, n))
print(pow(4, e, n))
print(pow(8, e, n))

'''
169169912654178
128509160179202
518818742414340
358553002064450
'''

首先,审计题目,我们已知c,c1,c2,c3三个条件,其中,这四个数有以下关系:

c = m^e mod n

c1 = 2^e mod n

c2 = 4^e mod n

c3 = 8^e mod n

=>c1**2-c2= k1*n   and    c1*c2-c3  = k2*n

于是,我们找到这两个数的最大公因数,这个数中一定包含我们想要的n这个值

import gmpy2
import sympy
print(gmpy2.gcd(c1*c1-c2,c1*c2-c3))

 于是我们得到了我们想要的n值1054494004042394,这个数很小,我们可以将其分解得到

sage: factor(1054494004042394)
2 * 18195301 * 28977097

由于我们知道p、q都是质数,所以,在得到的分解中只需取其大质数即可。接下来,我们需要考虑求解e值的大小

已知的条件为:

2^e = c1 mod n   在这其中,除了e其余条件我们都已知,在这里,我们需要使用离散对数求解的思路:

Shanks’s Babystep-Giantstep Algorithm算法:

1、n=[ √n ]+1

2、构造两个列表

  list1=[1,g,g^2,g^3,......,g^n]

  list2=[h,hg^(-n),hg^(-2n),......,hg^(-n**2)]

3、在两个列表中,找到两个相同的数 g^i=hg^(-jn)

=>g^(i+jn)=h mod n

4、我们所求的e=i+jn

 在python中,有两个可以很简单的实现关于幂的求解:

1、求解a^x = 1 mod n

sagemath:order=Zmod(n)(a).multiplicative_order()

2、求解g^x = a mod n

python(sympy库)  x=sympy.discrete_log(n,a,g)

 于是,根据以上条件,我们可以求解出e值,并对其进行rsa解密:

p = 18195301
q = 28977097
n=p*q
phi=(p-1)*(q-1)
e=sympy.discrete_log(n,c1,2)
d=gmpy2.invert(e,phi)

from Crypto.Util.number import *
print(long_to_bytes(gmpy2.powmod(c,d,n)))

exp:

c  = 169169912654178
c1 = 128509160179202
c2 = 518818742414340
c3 = 358553002064450

import gmpy2
import sympy
print(gmpy2.gcd(c1*c1-c2,c1*c2-c3))

p = 18195301
q = 28977097
n=p*q
phi=(p-1)*(q-1)
e=sympy.discrete_log(n,c1,2)
d=gmpy2.invert(e,phi)

from Crypto.Util.number import *
print(long_to_bytes(gmpy2.powmod(c,d,n)))

 得到:

b'345y!'

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值