basectf-没有n啊_pro

from Crypto.Util.number import *
import gmpy2

flag=b'BaseCTF{}'
m=bytes_to_long(flag)
p=getPrime(128)
q=getPrime(128)

n=p*q
e=65537

phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)

assert d<phi

c=pow(m,e,n)
print("c =",c)
print("e =",e)
print("d =",d)

这题没有给出n,注意到d<phi,我们等式e*d=1+k*phi

如果d<phi,那么k<e,我们可以通过暴破的方法求e,d的组合找到phi,phi的位数可以推测是256

然后我们分解phi,对它的因数排列组合,求得它的p和q,需要一定的代码能力

from Crypto.Util.number import *
import itertools
c = 78919950899709764543039048006935881842075789773495004639436106636461009323420
e = 65537
d = 13002488326322253055272696035053386340217207134816593767440035447757509399233
p_bits=128
q_bits=128
def get_phi(e, d):
    k_phi = e*d -1
    result = []
    for k in range(e,2,-1):
        if k_phi % k == 0:
            tmp = k_phi // k
            if int(tmp).bit_length()==p_bits+q_bits:
                result.append(tmp)
    return result
def main():
    phi_list = get_phi(e,d)  #获得可能的phi_n列表
    count = len(phi_list)
    print(f'一共有{count}个可能的phi')
    count = 0
    for phi in phi_list:
        count += 1
        print(f'{count} 正在尝试爆破 {phi}')
        factors = factor(phi)  # 分解phi_n得到质因子列表
        result = []
        for i in factors:
            num, times = int(i[0]), i[1]
            result += [num] * times

        if len(factors)>1:
            s = set()
            for r in range(1, len(result) + 1):
                combination = list(itertools.combinations(result, r))
                for i in combination:
                    s.add(i)
            ans=[]
            for i in s:
                tmp=1
                for j in i:
                    tmp=tmp*j
                ans.append(tmp)
            for num in ans:
                if int(num+1).bit_length()==p_bits and is_prime(num+1):
                    p = num+1
                    q = phi // num + 1
                    if is_prime(q):
                        n = p * q
                        flag=long_to_bytes(int(pow(c,d,n)))
                        if b'BaseCTF' in flag:
                            print(flag)
                            return


if name == '__main__':
    main()
#b'BaseCTF{3e226a94-babb27696416}'

排列组合方法就是把因数每个因数的组合都求出来,并计算乘积,然后代入比较是不是符合条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值