Crypto练习-六月练习部分题目

第一题:

题目:
himt: 爆破、仿射加密变形

from secret import flag

assert flag.startswith(b'flag{') and flag.endswith(b'}')
table = "!\"#$%&'()*+,-.:<=>?@[\]^_{}ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"


def Enc(m: bytes) -> bytes:
    m = m.decode()
    cipher = ''
    for i in m:
        x = table.index(i)
        x = pow(x, -1, len(table))
        Index = (20 * x + 24) % len(table)
        cipher += table[Index]
    return cipher.encode()


m = flag[5:-1]
c = Enc(m.swapcase())
print(c)  # b'u-*a058*way08w8M*nwJ51q0sw-?vv8yu**8'

解法一(正向爆破):

table = "!\"#$%&'()*+,-.:<=>?@[\]^_{}ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
c = b'u-*a058*way08w8M*nwJ51q0sw-?vv8yu**8'
c = c.decode()
cm_dict = {}
for i in range(1, len(table)):
    x = i
    x = pow(x, -1, len(table))
    Index = (20 * x + 24) % len(table)
    cm_dict[Index] = i
flag = ''
for ci in c:
    ci = table.index(ci)
    Index = cm_dict[ci]
    m = table[Index]
    flag += m
flag = f"flag{{{flag.swapcase()}}}"
print(flag)

解法二(数论解密):

table = "!\"#$%&'()*+,-.:<=>?@[\]^_{}ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
cipher = ''
name = b'u-*a058*way08w8M*nwJ51q0sw-?vv8yu**8'
for i in name:
    Index = table.index(chr(i))
    x = 20 * pow((Index-24),-1,89)
    cipher += table[x % len(table)]
print(cipher.swapcase())
  • 数论详细说明如下:

第二题:

题目(第三届粤海杯-决赛Crypto1):

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

m = bytes_to_long(flag)

e = 65537
p = getPrime(1024)#生成一个1024二进制位的素数
q = getPrime(1024)
n = p * q

m = m * 2024 * q
c = pow(m, e, n)
print('c =', c)
print('n =', n)
#c = 11545622607408935458241292536059990101167349630718109609294965462438709273782489441876212917886133281927174501984195623922748845334472739773510801470970817720781268388230179515316476418724726975224719347630031080136490291075031534070900765922279400252680537756834228968929053004372347793194650613987769765467274552851439489471383254054865141037525723254945136184257590195301295660928232207262269582068083178544307777339982522032814759798399706632838087407405751960220739155606798371470343902512348951743472905649502921293269075476246772249983778876956091712601912931337782047911042303929198516654456415853368630203339
#n = 16685436900538999627958075836984455711275215227654508118866426820576750648214363814042620418604845678203948296168102845978815414728545576069310308602991967303882570151371842717385425660457439491696199859652579599985098514579849352058139823030426869537044169471423155839169977271312291018942482182102617647133320398924105420264097756185821980304410848122362329683629865399937502419424391684348738913383188330657655742401743281171234628370950482823006140502343675646036865574770126732307009918543130249736003273056079941336418478673038446442067464892523213081977061437393902307236265097311007382158394034241317995279579

exp:

因为m的因子有q,所以找到c和n的最大公约数即为q。从n再解出p。

from Crypto.Util.number import *
import gmpy2
import libnum
c = 11545622607408935458241292536059990101167349630718109609294965462438709273782489441876212917886133281927174501984195623922748845334472739773510801470970817720781268388230179515316476418724726975224719347630031080136490291075031534070900765922279400252680537756834228968929053004372347793194650613987769765467274552851439489471383254054865141037525723254945136184257590195301295660928232207262269582068083178544307777339982522032814759798399706632838087407405751960220739155606798371470343902512348951743472905649502921293269075476246772249983778876956091712601912931337782047911042303929198516654456415853368630203339
n = 16685436900538999627958075836984455711275215227654508118866426820576750648214363814042620418604845678203948296168102845978815414728545576069310308602991967303882570151371842717385425660457439491696199859652579599985098514579849352058139823030426869537044169471423155839169977271312291018942482182102617647133320398924105420264097756185821980304410848122362329683629865399937502419424391684348738913383188330657655742401743281171234628370950482823006140502343675646036865574770126732307009918543130249736003273056079941336418478673038446442067464892523213081977061437393902307236265097311007382158394034241317995279579
q = math.gcd(c,n)
p = n // q
e = 65537
print(p)
# n = p * q
phi = (p - 1) * (q - 1)
print(phi)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
m = m // (2024*q)
print(long_to_bytes(m))#这里记得转换一下

第三题:

题目(第三届粤海杯-决赛Crypto2):

from hashlib import md5
from secret import hint
from Crypto.Util.strxor import strxor

hint1 = hint[:6] #前六位
hint2 = hint[6:] #从第气位开始
assert hint1.islower() #判断是一个小写字母
print(md5(hint1).hexdigest())
print(strxor(hint1, hint2).decode())

"""
b5dd60e56f64aa1d259ab21c3973205f
TCUI_B
"""

exp:

可知 hint1 6 位小写字母组成,知道它的 md5 值,可以尝试爆破即可得到 hint1
有了 hint1 ,又已知 hint1 异或 hint2 的结果为 TCUI_B ,则 : hint2 = hint1 异或 TCUI_B
import string
from tqdm import *
from hashlib import md5
from itertools import product
from Crypto.Util.strxor import strxor
hint1_c= "b5dd60e56f64aa1d259ab21c3973205f"
hint1_xor_hint2 = 'TCUI_B'
table = string.ascii_lowercase
for hint1 in tqdm(product(table, repeat=6)):
    hint1 = ''.join(hint1).encode()
    if md5(hint1).hexdigest() == hint1_c:
        hint2 = strxor(hint1, hint1_xor_hint2.encode())
        hint = hint1+hint2
        print(hint) # tryxor 1,100
        break
得到 hint: tryxor 1,100 ,容易想到要对给出的 cipher 进行逐位异或(范围从 1 100 进行尝试)
发现得到的内容都没有出现 flag ,应想到还有一层编码,由题目名容易联想到 base64 ,故而得解
import base64
cipher = b"Bu`pB+kaVr]oV\NqBK(*B\IbTL|pUuQlU*QoBr^uTLZpU*I*VLU-VLB!"
for t in range(1,101):
    c = ""
    for i in cipher:
        c += chr(i ^ t)
    try:
        msg = base64.b64decode(c)
        if b"flag" in msg:
            print(msg) # flag{261045be-6d43-7a2b-3b0f1f-0a3d653956}
            break
    except:
        continue

第四题:

题目:给出n, c1, c2, e1*e2

n = 23723414709663043409146354803167768676484239031400646854344921581190842455020298542679503185959169237351051283957808491272176607589972102017725217000980459409011765777305036376238334392654701713028578404550441412521528096494483705166107924141060306111730935285286442299028811733353145813755051318853095870353494707151967367912118298118285822794149957221321943818652577443815883589657620731416673718056733736043424734846424920674873434253469199349509358967749850577159394268891674156450757240830233448999712357318363199170045863588924264511829817509100474166090712813299549787004962346680319872798058231188915628383591

c1 = 19054912774147628727553917598318536324166149639543661440938862373325472740612249436160410830877486186040052106255634085434218097705885466041251507988011368642912696888436661688751400979996939440386005462275597837891144799805829564596722747856176178371417553527156064062175120040399642658034642303212443343190336774432678439552199370842494606152369382835846688899438806677242794145486160825601378269966409132805334341258559358175137602547810978801876853296509228350723466401954436323165165393596214066597752251797884080416877041663915509051711571979131521014273115893792023266190735124851850698647470042538070138972920

c2 = 4490538789057573761504993536020749252128430743130655544771616036039597648387562955542457059064263092943953642271064630845544109444089794366487650060454509019455549834788373801758638846202744776342542046709631245793895398748825742566870869785973680707337905651332408048050432199901437246930344414459178264677544957506430818815995656423679626408760273187218494529527907212920442401843942300205444207127386748755283120742011676190160487038975352496744040261653217263840760717217725774971768938832680363884456641540497915440248468759706550639924866379591404304501009876129733453810653383380691467000199986316814509832670

e = e1*e2

e = 104481

解法一:(这种做法有点不稳,有些题目做不出?)

题目给了两个c、两个e和n,推测为共模攻击,但e1和e2给的是乘积,根据共模攻击的要求,e1和e2互质,且需要是整除,可通过脚本爆破:

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

n=23723414709663043409146354803167768676484239031400646854344921581190842455020298542679503185959169237351051283957808491272176607589972102017725217000980459409011765777305036376238334392654701713028578404550441412521528096494483705166107924141060306111730935285286442299028811733353145813755051318853095870353494707151967367912118298118285822794149957221321943818652577443815883589657620731416673718056733736043424734846424920674873434253469199349509358967749850577159394268891674156450757240830233448999712357318363199170045863588924264511829817509100474166090712813299549787004962346680319872798058231188915628383591
c1=19054912774147628727553917598318536324166149639543661440938862373325472740612249436160410830877486186040052106255634085434218097705885466041251507988011368642912696888436661688751400979996939440386005462275597837891144799805829564596722747856176178371417553527156064062175120040399642658034642303212443343190336774432678439552199370842494606152369382835846688899438806677242794145486160825601378269966409132805334341258559358175137602547810978801876853296509228350723466401954436323165165393596214066597752251797884080416877041663915509051711571979131521014273115893792023266190735124851850698647470042538070138972920
c2=4490538789057573761504993536020749252128430743130655544771616036039597648387562955542457059064263092943953642271064630845544109444089794366487650060454509019455549834788373801758638846202744776342542046709631245793895398748825742566870869785973680707337905651332408048050432199901437246930344414459178264677544957506430818815995656423679626408760273187218494529527907212920442401843942300205444207127386748755283120742011676190160487038975352496744040261653217263840760717217725774971768938832680363884456641540497915440248468759706550639924866379591404304501009876129733453810653383380691467000199986316814509832670
e= 104481
e1e2 = e

for e1 in range(2,e):
    e2=e//e1
    if( e%e1==0 and gcd(e1, e2)==1):
        s = gcdext(e1, e2)  # gmpy2.gcdext(),扩展欧几里得算法,返回tuple元组,满足s[1]*e1+s[2]*e2=1
        m = pow(c1, s[1], n) * pow(c2, s[2], n) % n  # 获取明文m
        m = long_to_bytes(m)
        if(b"flag" in m):
            print(m)

解法二:

参考文章:【密码学RSA】共模攻击原理详解_已知e1*e2的共模攻击题_rsa共模攻击原理-CSDN博客

n = 23723414709663043409146354803167768676484239031400646854344921581190842455020298542679503185959169237351051283957808491272176607589972102017725217000980459409011765777305036376238334392654701713028578404550441412521528096494483705166107924141060306111730935285286442299028811733353145813755051318853095870353494707151967367912118298118285822794149957221321943818652577443815883589657620731416673718056733736043424734846424920674873434253469199349509358967749850577159394268891674156450757240830233448999712357318363199170045863588924264511829817509100474166090712813299549787004962346680319872798058231188915628383591
c1 = 19054912774147628727553917598318536324166149639543661440938862373325472740612249436160410830877486186040052106255634085434218097705885466041251507988011368642912696888436661688751400979996939440386005462275597837891144799805829564596722747856176178371417553527156064062175120040399642658034642303212443343190336774432678439552199370842494606152369382835846688899438806677242794145486160825601378269966409132805334341258559358175137602547810978801876853296509228350723466401954436323165165393596214066597752251797884080416877041663915509051711571979131521014273115893792023266190735124851850698647470042538070138972920
c2 = 4490538789057573761504993536020749252128430743130655544771616036039597648387562955542457059064263092943953642271064630845544109444089794366487650060454509019455549834788373801758638846202744776342542046709631245793895398748825742566870869785973680707337905651332408048050432199901437246930344414459178264677544957506430818815995656423679626408760273187218494529527907212920442401843942300205444207127386748755283120742011676190160487038975352496744040261653217263840760717217725774971768938832680363884456641540497915440248468759706550639924866379591404304501009876129733453810653383380691467000199986316814509832670
e1e2 = 104481

import libnum
import gmpy2

def rsa_gongmo_def(e1,e2,c1,c2,n):
    s,s1,s2 = gmpy2.gcdext(e1, e2)
    m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
    return int(m)


def de(c, e, n):  # 因为此时的m不是真正的m,而是m^k,所以对m^k进行爆破
    k = 0
    while k < 1000:  # 指定k小于1000
        mk = c + n * k
        flag, true1 = gmpy2.iroot(mk, e)  # 返回的第一个数值为开方数,第二个数值为布尔型,可整除为true
        if True == true1:
            return flag
        k += 1

for e1 in range(2, e1e2):
    if e1e2 % e1 == 0:  # 爆破可整除的e
        e2 = e1e2 // e1
        c = rsa_gongmo_def(e1, e2, c1, c2, n)
        e = gmpy2.gcd(e1, e2)
        m1 = de(c, e, n)
        if m1:  # 指定输出m1
            print(libnum.n2s(int(m1)))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值