记一道rsa题---第一届“长城杯”网络安全大赛

本文介绍了RSA加密算法的原理,包括如何通过素数生成密钥对,以及如何利用Python实现加密和解密过程。在部分1中,通过枚举方法找到了满足条件的p、q,解密了第一部分密文;在部分2中,通过分解大数x为四个因子,成功解密了第二部分密文。整个过程展示了RSA在实际问题中的应用。
摘要由CSDN通过智能技术生成

baby_rsa

题目:

#!/usr/bin/env python3

from Crypto.Util.number import *
from secret import flag, v1, v2, m1, m2


def enc_1(val):
    p, q = pow(v1, (m1+1))-pow((v1+1), m1), pow(v2, (m2+1))-pow((v2+1), m2)
    assert isPrime(p) and isPrime(q) and (p*q).bit_length() == 2048 and q < p < q << 3
    return pow(val, 0x10001, p*q)


def enc_2(val):
    assert val.bit_length() < 512
    while True:
        fac = [getPrime(512) for i in range(3)]
        if isPrime(((fac[0]+fac[1]+fac[2]) << 1) - 1):
            n = fac[0]*fac[1]*fac[2]*(((fac[0]+fac[1]+fac[2]) << 1) - 1)
            break
    c = pow(val, 0x10001, n)
    return (c, n, ((fac[0]+fac[1]+fac[2]) << 1) - 1)


if __name__ == "__main__":
    assert flag[:5] == b'flag{'
    plain1 = bytes_to_long(flag[:21])
    plain2 = bytes_to_long(flag[21:])
    print(enc_1(plain1))
    print(enc_2(plain2))

'''
15808773921165746378224649554032774095198531782455904169552223303513940968292896814159288417499220739875833754573943607047855256739976161598599903932981169979509871591999964856806929597805904134099901826858367778386342376768508031554802249075072366710038889306268806744179086648684738023073458982906066972340414398928411147970593935244077925448732772473619783079328351522269170879807064111318871074291073581343039389561175391039766936376267875184581643335916049461784753341115227515163545709454746272514827000601853735356551495685229995637483506735448900656885365353434308639412035003119516693303377081576975540948311
(40625981017250262945230548450738951725566520252163410124565622126754739693681271649127104109038164852787767296403697462475459670540845822150397639923013223102912674748402427501588018866490878394678482061561521253365550029075565507988232729032055298992792712574569704846075514624824654127691743944112075703814043622599530496100713378696761879982542679917631570451072107893348792817321652593471794974227183476732980623835483991067080345184978482191342430627490398516912714451984152960348899589532751919272583098764118161056078536781341750142553197082925070730178092561314400518151019955104989790911460357848366016263083, 43001726046955078981344016981790445980199072066019323382068244142888931539602812318023095256474939697257802646150348546779647545152288158607555239302887689137645748628421247685225463346118081238718049701320726295435376733215681415774255258419418661466010403928591242961434178730846537471236142683517399109466429776377360118355173431016107543977241358064093102741819626163467139833352454094472229349598479358367203452452606833796483111892076343745958394932132199442718048720633556310467019222434693785423996656306612262714609076119634814783438111843773649519101169326072793596027594057988365133037041133566146897868269, 39796272592331896400626784951713239526857273168732133046667572399622660330587881579319314094557011554851873068389016629085963086136116425352535902598378739)
'''

part1 

def enc_1(val):
    p, q = pow(v1, (m1+1))-pow((v1+1), m1), pow(v2, (m2+1))-pow((v2+1), m2)
    assert isPrime(p) and isPrime(q) and (p*q).bit_length() == 2048 and q < p < q << 3
    return pow(val, 0x10001, p*q)

由代码可以得到:

p=v1^{m1+1}-(v1+1)^{m1}

q = v2^{m2+1}-(v2+1)^{m2}

且对p、q有条件限制:

1、p、q均是素数

2、p*q的bit位等于2048

3、q < p < 8q

可以知道p、q的长度都是小于2048的,可以通过枚举v、m来得到范围内满足条件的所有p或q的值,放入一个集合内,再在这个集合内进行枚举出正确的p、q,代码如下:

#part1
c1 = 15808773921165746378224649554032774095198531782455904169552223303513940968292896814159288417499220739875833754573943607047855256739976161598599903932981169979509871591999964856806929597805904134099901826858367778386342376768508031554802249075072366710038889306268806744179086648684738023073458982906066972340414398928411147970593935244077925448732772473619783079328351522269170879807064111318871074291073581343039389561175391039766936376267875184581643335916049461784753341115227515163545709454746272514827000601853735356551495685229995637483506735448900656885365353434308639412035003119516693303377081576975540948311
e1 = 65537

pq = []
for v in range(400):
    for m in range(400):
        p = pow(v,(m+1))-pow((v+1),m)
        if len(bin(p)[2:]) < 2048 and isPrime(p):
            pq.append(p)
for p in pq:
    for q in pq:
        n1 = p*q
        if len(bin(n1)[2:]) == 2048:
            d1 = invert(e1,(p-1)*(q-1))
            m1 = pow(c1,d1,n1)
            flag = long_to_bytes(m1)
            if b'flag{' in flag:
                print(flag)

part2 

def enc_2(val):
    assert val.bit_length() < 512
    while True:
        fac = [getPrime(512) for i in range(3)]
        if isPrime(((fac[0]+fac[1]+fac[2]) << 1) - 1):
            n = fac[0]*fac[1]*fac[2]*(((fac[0]+fac[1]+fac[2]) << 1) - 1)
            break
    c = pow(val, 0x10001, n)
    return (c, n, ((fac[0]+fac[1]+fac[2]) << 1) - 1)

记 x = fac[0]*fac[1]*fac[2]

y = ((fac[0]+fac[1]+fac[2]) << 1) - 1

因为c =m^{e} modn,且n =fac[0]*fac[1]*fac[2]*(((fac[0]+fac[1]+fac[2]) << 1) - 1)= x*y, 故c =m^{e} modx*y,将其分开得到:

c =m^{e} modx和 c =m^{e} mody,利用c =m^{e} modx构造新的rsa解密,对x进行分解可以得到4个因子,之后便是基础的rsa解密,代码如下:

#part2
e2 = 65537
c2 = 40625981017250262945230548450738951725566520252163410124565622126754739693681271649127104109038164852787767296403697462475459670540845822150397639923013223102912674748402427501588018866490878394678482061561521253365550029075565507988232729032055298992792712574569704846075514624824654127691743944112075703814043622599530496100713378696761879982542679917631570451072107893348792817321652593471794974227183476732980623835483991067080345184978482191342430627490398516912714451984152960348899589532751919272583098764118161056078536781341750142553197082925070730178092561314400518151019955104989790911460357848366016263083
n2 = 43001726046955078981344016981790445980199072066019323382068244142888931539602812318023095256474939697257802646150348546779647545152288158607555239302887689137645748628421247685225463346118081238718049701320726295435376733215681415774255258419418661466010403928591242961434178730846537471236142683517399109466429776377360118355173431016107543977241358064093102741819626163467139833352454094472229349598479358367203452452606833796483111892076343745958394932132199442718048720633556310467019222434693785423996656306612262714609076119634814783438111843773649519101169326072793596027594057988365133037041133566146897868269
#n2 = 191*193*627383*1859355639056989338847729886215084320013550560439241610057371464443668166453664500865174247660203446208131621966684387189121472932263450155428982061395111044679950753816414282942636019897750209949937717881413823952091423640659878296010412658344713439244770180457400325541493186854703180053691731596197238201363111053528501245160357253774375411526857827842825019859291800622538200724857835739888753732012856112635184060331441747542167843105976327845423935402822864894596846745465781342565264427930954562609611327939077769568270876754335269640277726607195276868129620895284648898858733965899439317638568413061
x = 39796272592331896400626784951713239526857273168732133046667572399622660330587881579319314094557011554851873068389016629085963086136116425352535902598378739
#x = 191*193*627383*1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491
p2 = 191
q2 = 193
r = 627383
s = 1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491

d2 = invert(e2,(p2-1)*(q2-1)*(r-1)*(s-1))
m2 = pow(c2,d2,x)
print(long_to_bytes(m2))

 整体代码如下:

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

#part1
c1 = 15808773921165746378224649554032774095198531782455904169552223303513940968292896814159288417499220739875833754573943607047855256739976161598599903932981169979509871591999964856806929597805904134099901826858367778386342376768508031554802249075072366710038889306268806744179086648684738023073458982906066972340414398928411147970593935244077925448732772473619783079328351522269170879807064111318871074291073581343039389561175391039766936376267875184581643335916049461784753341115227515163545709454746272514827000601853735356551495685229995637483506735448900656885365353434308639412035003119516693303377081576975540948311
e1 = 65537

pq = []
for v in range(400):
    for m in range(400):
        p = pow(v,(m+1))-pow((v+1),m)
        if len(bin(p)[2:]) < 2048 and isPrime(p):
            pq.append(p)
for p in pq:
    for q in pq:
        n1 = p*q
        if len(bin(n1)[2:]) == 2048:
            d1 = invert(e1,(p-1)*(q-1))
            m1 = pow(c1,d1,n1)
            flag = long_to_bytes(m1)
            if b'flag{' in flag:
                print(flag)

#part2
e2 = 65537
c2 = 40625981017250262945230548450738951725566520252163410124565622126754739693681271649127104109038164852787767296403697462475459670540845822150397639923013223102912674748402427501588018866490878394678482061561521253365550029075565507988232729032055298992792712574569704846075514624824654127691743944112075703814043622599530496100713378696761879982542679917631570451072107893348792817321652593471794974227183476732980623835483991067080345184978482191342430627490398516912714451984152960348899589532751919272583098764118161056078536781341750142553197082925070730178092561314400518151019955104989790911460357848366016263083
n2 = 43001726046955078981344016981790445980199072066019323382068244142888931539602812318023095256474939697257802646150348546779647545152288158607555239302887689137645748628421247685225463346118081238718049701320726295435376733215681415774255258419418661466010403928591242961434178730846537471236142683517399109466429776377360118355173431016107543977241358064093102741819626163467139833352454094472229349598479358367203452452606833796483111892076343745958394932132199442718048720633556310467019222434693785423996656306612262714609076119634814783438111843773649519101169326072793596027594057988365133037041133566146897868269
#n2 = 191*193*627383*1859355639056989338847729886215084320013550560439241610057371464443668166453664500865174247660203446208131621966684387189121472932263450155428982061395111044679950753816414282942636019897750209949937717881413823952091423640659878296010412658344713439244770180457400325541493186854703180053691731596197238201363111053528501245160357253774375411526857827842825019859291800622538200724857835739888753732012856112635184060331441747542167843105976327845423935402822864894596846745465781342565264427930954562609611327939077769568270876754335269640277726607195276868129620895284648898858733965899439317638568413061
x = 39796272592331896400626784951713239526857273168732133046667572399622660330587881579319314094557011554851873068389016629085963086136116425352535902598378739
#x = 191*193*627383*1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491
p2 = 191
q2 = 193
r = 627383
s = 1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491

d2 = invert(e2,(p2-1)*(q2-1)*(r-1)*(s-1))
m2 = pow(c2,d2,x)
print(long_to_bytes(m2))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值