DASCTF-CBCTF-2023 Crypto部分复现

文章目录


这次比赛没打,记错时间了,看了一下,如果去做的话大概也只能做出那两道简单的题,还是太菜啦

EzRSA

题目描述:

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

def padding(f):
    random_chars = bytes([random.randint(0, 255) for _ in range(32)])
    f = f + random_chars
    return f

def guess_p(p):
    e = 65537
    
    P = p
    n1 = getPrime(512)*getPrime(512)
    with open('enc.txt', 'w+') as f:
        while jacobi(2,n1) == 1:
            n1 = getPrime(512)*getPrime(512)
        while P:
            pad = random.randint(0, 2**2023)**2 
            message = pad << 1 + P % 2
            cipher = pow(message, e, n1)
            f.write(str(cipher)+'n')
            P //= 2
    print("n1 = "+ str(n1) )    
    
def guess_q(q):
    
    def encrypt(q, n):
        e = random.randint(1000,2000)
        noise = random.randint(0, n - 1)
        c = pow(q+noise,e,n)
        return e, noise,c 
    
    n2 = getPrime(512)*getPrime(512)
    e1, noise1, c1 = encrypt(q, n2)
    e2, noise2, c2 = encrypt(q, n2)
    print("n2 = "+ str(n2) ) 
    print('(e1, noise1, c1) =', (e1,noise1,c1))
    print('(e2, noise2, c2) =', (e2,noise2,c2))
p = getPrime(512)
q = getPrime(512)

n = p*q
guess_p(p)
guess_q(q)
e = 0x10001
flag = padding(flag)
m = bytes_to_long(flag)
c = pow(m,e,n)

print("c = " + str(c))
'''
n1 = 65634094430927080732256164808833233563732628654160389042977689628512527168256899310662239009610512772020503283842588142453533499954947692968978190310627721338357432052800695091789711809256924541784954080619073213358228083200846540676931341013554634493581962527475555869292091755676130810562421465063412235309
n2 = 103670293685965841863872863719573676572683187403862749665555450164387906552249974071743238931253290278574192713467491802940810851806104430306195931179902098180199167945649526235613636163362672777298968943319216325949503045377100235181706964846408396946496139224344270391027205106691880999410424150216806861393
(e1, noise1, c1) = (1743, 44560588075773853612820227436439937514195680734214431948441190347878274184937952381785302837541202705212687700521129385632776241537669208088777729355349833215443048466316517110778502508209433792603420158786772339233397583637570006255153020675167597396958251208681121668808253767520416175569161674463861719776, 65643009354198075182587766550521107063140340983433852821580802983736094225036497335607400197479623208915379722646955329855681601551282788854644359967909570360251550766970054185510197999091645907461580987639650262519866292285164258262387411847857812391136042309550813795587776534035784065962779853621152905983)
(e2, noise2, c2) = (1325, 35282006599813744140721262875292395887558561517759721467291789696459426702600397172655624765281531167221787036009507833425145071265739486735993631460189629709591456017092661028839951392247601628468621576100035700437892164435424035004463142959219067199451575338270613300215815894328788753564798153516122567683, 50327632090778183759544755226710110702046850880299488259739672542025916422119065179822210884622225945376465802069464782311211031263046593145733701591371950349735709553105217501410716570601397725812709771348772095131473415552527749452347866778401205442409443726952960806789526845194216490544108773715759733714)
c = 124349762993424531697403299350944207725577290992189948388824124986066269514204313888980321088629462472088631052329128042837153718129149149661961926557818023704330462282009415874674794190206220980118413541269327644472633791532767765585035518183177197863522573410860341245613331398610013697803459403446614221369
'''

题目分析:
gen_q:
看到jacobi(2,n1)便知道是二次剩余的知识
c = ( 2 ∗ a 2 ) e ,当 P % 2 = 0 c = ( 2 ∗ a ) 2 ∗ e ,当 P % 2 = 1 c ( n 1 − 1 ) / / 2 ≡ ( 2 ∗ a 2 ) e ∗ ( n 1 − 1 ) / / 2 ≡ − 1 ∗ 1 m o d    n 1 ① c ( n 1 − 1 ) / / 2 ≡ ( 2 ∗ a ) 2 ∗ e ∗ ( n 1 − 1 ) / / 2 ≡ ( 2 ∗ a ) e ∗ ( n 1 − 1 ) ≡ 1 m o d    n 1 ② ⇒ j a c o b i ( e n c i , n 1 ) = − 1 , p = 0 + p c = (2 * a^2)^e ,当P \% 2 = 0\\ c = (2 * a)^{2*e},当P \% 2 = 1\\ c^{(n1 - 1) // 2} \equiv (2 * a^2)^{e *(n1 - 1) //2} \equiv -1 * 1 \mod n1 ①\\ c^{(n1 - 1)//2} \equiv (2*a)^{2*e*(n1 - 1)//2} \equiv(2 * a)^{e * (n1 - 1)} \equiv 1 \mod n1②\\ \Rightarrow jacobi(enc_i,n1) = -1,p = 0 + p\\ c=(2a2)e,当P%2=0c=(2a)2e,当P%2=1c(n11)//2(2a2)e(n11)//211modn1①c(n11)//2(2a)2e(n11)//2(2a)e(n11)1modn1②jacobi(enci,n1)=1,p=0+p
gen_q:
相关消息攻击直接解啦

exp:

import binascii
import libnum
from gmpy2 import *
from Crypto.Util.number import *
n1 = 65634094430927080732256164808833233563732628654160389042977689628512527168256899310662239009610512772020503283842588142453533499954947692968978190310627721338357432052800695091789711809256924541784954080619073213358228083200846540676931341013554634493581962527475555869292091755676130810562421465063412235309
(e1, noise1, c1) = (1743, 44560588075773853612820227436439937514195680734214431948441190347878274184937952381785302837541202705212687700521129385632776241537669208088777729355349833215443048466316517110778502508209433792603420158786772339233397583637570006255153020675167597396958251208681121668808253767520416175569161674463861719776, 65643009354198075182587766550521107063140340983433852821580802983736094225036497335607400197479623208915379722646955329855681601551282788854644359967909570360251550766970054185510197999091645907461580987639650262519866292285164258262387411847857812391136042309550813795587776534035784065962779853621152905983)
(e2, noise2, c2) = (1325, 35282006599813744140721262875292395887558561517759721467291789696459426702600397172655624765281531167221787036009507833425145071265739486735993631460189629709591456017092661028839951392247601628468621576100035700437892164435424035004463142959219067199451575338270613300215815894328788753564798153516122567683, 50327632090778183759544755226710110702046850880299488259739672542025916422119065179822210884622225945376465802069464782311211031263046593145733701591371950349735709553105217501410716570601397725812709771348772095131473415552527749452347866778401205442409443726952960806789526845194216490544108773715759733714)
c = 124349762993424531697403299350944207725577290992189948388824124986066269514204313888980321088629462472088631052329128042837153718129149149661961926557818023704330462282009415874674794190206220980118413541269327644472633791532767765585035518183177197863522573410860341245613331398610013697803459403446614221369
n2 = 103670293685965841863872863719573676572683187403862749665555450164387906552249974071743238931253290278574192713467491802940810851806104430306195931179902098180199167945649526235613636163362672777298968943319216325949503045377100235181706964846408396946496139224344270391027205106691880999410424150216806861393

ciphers = []
with open('enc.txt') as f:
    for line in f.read().split('n'):
        if line.strip():
            ciphers.append(int(line.strip()))

p = ''
for i in ciphers:
    if jacobi(i,n1) == -1:
        p = '0' + p
    else:
        p = '1' + p

p = int(p,2)

def franklinReiter(n,e1,e2,c1,c2,noise1,noise2):
    PR.<x> = PolynomialRing(Zmod(n))
    g1 = (x + noise1)^e1 - c1
    g2 = (x + noise2)^e2 - c2

    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic() # 
    return -gcd(g1, g2)[0]

q=franklinReiter(n2,e1,e2,c1,c2,noise1,noise2)
q = 13189337905641321257372188436353844418280745284875462357019668708167547026960641869513283218672677712590326347601424108528959315675307896082223561007980457
p = 9473204278465588641589315677772678997836862033858760337441231265335880892205102590571357305720744128962068300763212493598006400853597404586755248901932203
e = 0x10001
phi = (p - 1) * (q - 1)
d = inverse(e,phi)
print(long_to_bytes(int(pow(c,d,p * q))))
# DASCTF{W05-y03r_m2st1r-j2c0b1_2nd_p01yn0mi2l!}

CB backpack

题目描述:

from random import shuffle

def gen_e():
    e = []
    for i in range(8):
        ee = [0]*3+[1]*3
        shuffle(ee)
        e += ee
    return e
    
e = gen_e()
nbit = len(e) # 48
flag = 'DASCTF{'+sha256(''.join([str(i) for i in e]).encode()).hexdigest()+'}'

a = [randint(1,2^nbit) for i in range(nbit)]

re = 0
for i in range(nbit):
    re += e[i]*a[i]

print(a)
print(re)

题目分析:
一开始看到,感觉很熟悉啊,这不妥妥的背包加密吗,结果。。。是我想简单了
又涉及到了知识盲区,跟着大佬的wp做了一遍,学习到了
总的来说就是数据给的不够大,直接用背包格解出不来,需要爆破几位,通过jsdn测试密度是否达标(d < 0.9408)
测试了一下,得爆破10位以上才能出结果,尽管爆破8位也满足d < 0.9408,但确实是得不到
这样的话我爆破12位吧

from math import *
n = 36
a = [65651991706497, 247831871690373, 120247087605020, 236854536567393, 38795708921144, 256334857906663, 120089773523233, 165349388120302, 123968326805899, 79638234559694, 259559389823590, 256776519514651, 107733244474073, 216508566448440, 39327578905012, 118682486932022, 263357223061004, 132872609024098, 44605761726563, 24908360451602, 237906955893793, 204469770496199, 7055254513808, 221802659519968, 169686619990988, 23128789035141, 208847144870760, 272339624469135, 269511404473473, 112830627321371, 73203551744776, 42843503010671, 118193938825623, 49625220390324, 230439888723036, 241486656550572, 107149406378865, 233503862264755, 269502011971514, 181805192674559, 152612003195556, 184127512098087, 165959151027513, 188723045133473, 241615906682300, 216101484550038, 81190147709444, 124498742419309]
a = a[12:]
d = n / log2(max(a))
N = ceil(1 / 2 * sqrt(n))
assert d < 0.9408, f"Density should be less than 0.9408 but was {d}."
print(d) # 0.7507444846333444

为了节省时间这里直接逆序,很快,1分钟就出来了

from tqdm import tqdm
a=[65651991706497, 247831871690373, 120247087605020, 236854536567393, 38795708921144, 256334857906663, 120089773523233, 165349388120302, 123968326805899, 79638234559694, 259559389823590, 256776519514651, 107733244474073, 216508566448440, 39327578905012, 118682486932022, 263357223061004, 132872609024098, 44605761726563, 24908360451602, 237906955893793, 204469770496199, 7055254513808, 221802659519968, 169686619990988, 23128789035141, 208847144870760, 272339624469135, 269511404473473, 112830627321371, 73203551744776, 42843503010671, 118193938825623, 49625220390324, 230439888723036, 241486656550572, 107149406378865, 233503862264755, 269502011971514, 181805192674559, 152612003195556, 184127512098087, 165959151027513, 188723045133473, 241615906682300, 216101484550038, 81190147709444, 124498742419309]
re=4051501228761632
A = a[12:]
bits=36
def ju(j):
    for i in j:
        if abs(i)!=1:
            return 0
    return 1
for i in tqdm(range(2^12,1,-1)):
    temp=[int(j) for j in bin(i)[2:].zfill(12)]
    t1,t2=temp[:6],temp[6:12]
    if sum(t1)!=3 or sum(t2)!=3:
        continue
    rr = sum([i*j for i,j in zip(temp,a[:12])])
    new_re = re - rr
    M=Matrix(ZZ,bits+1)
    for i in range(bits):
        M[i,i]=2
        M[i,-1]=A[i]
    for i in range(bits):
        M[-1,i]=1
    M[-1,-1]=new_re
    res=M.LLL()
    if ju(res[0][:-1]):
        print('find')
        print(temp)
        print(res[0])
        break

在这里插入图片描述
评论里说的另一种思路,也是给链接那位师傅的思路
构造:
M = ( 1 a 1 1 1 a 2 1 ⋱ ⋮ ⋮ 1 a 48 1 r e 24 ) M = \begin{pmatrix} 1&&&&&a_1&1\\ &1&&&&a_2&1\\ &&\ddots&&&\vdots&\vdots\\&&&1&&a_{48}&1\\ &&&&&re&24 \end{pmatrix} M= 111a1a2a48re11124
( e 1 , e 2 , . . . , e 48 , − 1 , − 1 ) ∗ M = ( e 1 , e 2 , . . . , e 48 , 0 , 0 ) (e_1,e_2,...,e_{48},-1,-1) * M = (e_1,e_2,...,e_{48},0,0) (e1,e2,...,e48,1,1)M=(e1,e2,...,e48,0,0)
所以说关键是ee = [0]*3+[1]*3这一串,我并没有想过去处理它,考虑不周

可以看看官方wp

CB ezDHKE
这题很常见也很简单就不说了
CB curve
CB cipher
这两题等有时间再继续复现吧

学习到了背包格爆破

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值