2024_Newstar_week3_Crypto

故事新编1

题目

python 复制代码
from hashlib import md5
zen1  = '''

'''
key1 = 
def enc1(plaintext, key):
    def shift_char(c, k):
        return chr(((ord(c) - ord('A') + (ord(k) - ord('A'))) % 26) + ord('A'))

    plaintext = plaintext.upper()
    key = key.upper()
    ciphertext = []
    key_index = 0

    for char in plaintext:
        if char.isalpha():
            ciphertext.append(shift_char(char, key[key_index % len(key)]))
            key_index += 1
        else:
            ciphertext.append(char)

    return ''.join(ciphertext)
print('enc = \'\'\'' + enc1(zen1, key1)+'\'\'\'')
flag = b'flag{'+md5(zen1.encode()).hexdigest().encode()+b'}'
print(flag)
#----------------------------------------------
enc = '''
TYBNBBZNT WF TYUMMK NAIB HYFZ.
XFIFBKWG AM CXBMYK BVNF CNITBWBB.
GVEJMX QL VXBHRJ NITV VIFXZRP.
WPFXEYQ QG OWNUXZ MBTV QBEJMBKTNXL.
TYSN JL JXNMMF GZUO GMLNXL.
GCSLTX QL VXBHRJ NITV WYGAS.
SDUHT QL PXOSAWLF
KMTXTJWYANZ VWNHMA.
GCWWJTT VULMG NJYO'M AIYVQOY WHPNOA NH JFRSE UAM KOEMG.
NDNIHCZB IZOPLCDTTBNR JSNLM QNZBNR.
MFEGLT LPHOEL BRNYS IILM LQZRFNMR.
CGFXAG RPJMBKBNEG GVDYOVMW.
'''

思路:维吉尼亚编码

这里没有key,需要根据频率分析得到对应key长度和key具体的值

这里我直接用得在线网站:https://guballa.de/vigenere-solver

发现这句话原来出自于《python之禅》

这里得到的解码结尾加上一个换行符,不懂出题人为啥这样搞

故事新编2

看了看编码后的字符,发现还是出自《python之禅》,这里我直接得到了解码后的字符(取巧做法)

没e这能玩?

python 复制代码
m = bytes_to_long(b'flag{*****}')
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
h1 = 1*p + 1*q + 1*r
h2 = 2*p + 3*q + 3*r
h3 = 9*p + 9*q + 6*r
print( "hint_of_pqr=" , h1 , h2 , h3 )
e = getPrime(64)
a_big_prime = getPrime( 512 )
hint = pow(a_big_prime,e,2**512)
print( "big_prime is: " , a_big_prime )
print( "hint is: " , hint )
n = p*q*r
c = pow( m , e , n )
print( "c=" , c )

这里什么都有,唯独不知道e

(a_big_prime)^e %(2**512)=hint

离散对数求解指数e

下面用到一个函数可以直接求解

e = sympy.discrete_log(2**512,hint,a_big_prime)

完整脚本:

python 复制代码
from Crypto.Util.number import *
import sympy
import gmpy2

h1=31142735238530997044538008977536563192992446755282526163704097825748037157617958329370018716097695151853567914689441893020256819531959835133410539308633497
h2=83244528500940968089139246591338465098116598400576450028712055615289379610182828415628469144649133540240957232351546273836449824638227295064400834828714760
h3=248913032538718194100308575844236838621741774207751338576000867909773931464854644505429950530402814602955352740032796855486666128271187734043696395254816172 
hint=1117823254118009923270987314972815939020676918543320218102525712576467969401820234222225849595448982263008967497960941694470967789623418862506421153355571
a_big_prime=10340528340717085562564282159472606844701680435801531596688324657589080212070472855731542530063656135954245247693866580524183340161718349111409099098622379
c=999238457633695875390868312148578206874085180328729864031502769160746939370358067645058746087858200698064715590068454781908941878234704745231616472500544299489072907525181954130042610756999951629214871917553371147513692253221476798612645630242018686268404850587754814930425513225710788525640827779311258012457828152843350882248473911459816471101547263923065978812349463656784597759143314955463199850172786928389414560476327593199154879575312027425152329247656310
p=h1*3-h2
r=(9*h1-h3)//3
q=h1-p-r
n=p*q*r
phi=(p-1)*(q-1)*(r-1)
e = sympy.discrete_log(2**512,hint,a_big_prime)
print(e)
print(gmpy2.gcd(e,phi))
d=gmpy2.invert(e,phi)
flag=pow(c,d,n)
print(long_to_bytes(flag))
# flag{th1s_2s_A_rea119_f34ggg}

不用谢喵

题目:

python 复制代码
from Crypto.Cipher import AES
from Crypto.Util.number import *
import os

KEY = b"fake_key_fake_ke"
FLAG = "flag{fake_flag_fake_flag}"  

def decrypt(c):
    AES_ECB = AES.new(KEY, AES.MODE_ECB)
    decrypted = AES_ECB.decrypt(long_to_bytes(c))

    return decrypted.hex()

def encrypt():
    iv = os.urandom(16)
    AES_CBC = AES.new(KEY, AES.MODE_CBC, iv)
    encrypted = AES_CBC.encrypt(FLAG.encode())
    print('iv:',iv.hex())

    return iv.hex() + encrypted.hex()

c=encrypt()
print('encrypt:',c)
print('decrypt:',decrypt(int(c,16)))

encrypt: f2040fe3063a5b6c65f66e1d2bf47b4c ddb206e4ddcf7524 932d25e92d57d346 8398730b59df851c bac6d65073f9e138
什么是AES啊😭,求求你帮我解密吧,我什么都会做的!!!!!😭

'''
什么都会做?那就去学习一下AES吧......
我这次就先给你解一下好了,不用谢喵
        #f2040fe3063a5b6c65f66e1d2bf47b4c   ddb206e4ddcf7524932d25e92d57d346   8398730b59df851cbac6d65073f9e138
decrypt: f9899749fec184d81afecd35da430bc3   94686e847d72141b3a955a4f6e920e7d   91cb599d92ba2a6ba51860bb5b32f23b
这对吗?哦不对不对,哦对的对的。
'''

思路:这里先是CBC加密,然后是ECB加密

但是根据题目并不能求出来key

CBC与ECB加密的区别如下:

我们知道AES一般是分成16个字节一块一块的加密

我们虽然不知道这里的key,但两次加密使用的key都是一样的

所以第二次的加密其实可以看成解密,但又不能完全看作是CBC的解密

因为解密缺少iv向量(这里我们有第一块的iv向量)

不过我们可以根据CBC加密得到的密文确定ECB的第二块初始向量

而这里我们加密的内容正好分成两块;

我们可以看出来这里

ECB加密后的第一块与iv初始向量异或得到的就是明文flag第一部分

ECB加密后的第二块与CBC加密后的第一块异或得到的就是明文flag第二部分

完整脚本如下:

python 复制代码
from Crypto.Cipher import AES
from Crypto.Util.number import *
import os

iv=0xf2040fe3063a5b6c65f66e1d2bf47b4c
f1=0x94686e847d72141b3a955a4f6e920e7d
f2=0x91cb599d92ba2a6ba51860bb5b32f23b
flag1=f1^iv
print(flag1)
print(long_to_bytes(flag1).decode(),end='')
flag2=f2^(int('ddb206e4ddcf7524932d25e92d57d346',16))
print(long_to_bytes(flag2).decode())
# flag{HOw_c4REfu1Ly_yOu_O65ERve!}

两个黄鹂鸣翠柳

题目:

python 复制代码
import random
from Crypto.Util.number import *
while 1:
    delta = getPrime(1024)
    p = getPrime(512)
    q = getPrime(512)
    N = p * q
    if delta<N:
        break
flag = b'flag{xxxxxxxxxxxxx}'
e = getPrime(10)
m = bytes_to_long(flag)
t1 = random.randint(0,255)
t2 = random.randint(0,255)
assert (t1 != t2)
m1 = m + t1 * delta
m2 = m + t2 * delta
c1 = pow(m1, e, N)
c2 = pow(m2, e, N)
print("e = ", e)
print("c1 = ", c1)
print("c2 = ", c2)
print("N = ", N)
print("delta = ", delta)

'''
e =  683
c1 =  56853945083742777151835031127085909289912817644412648006229138906930565421892378967519263900695394136817683446007470305162870097813202468748688129362479266925957012681301414819970269973650684451738803658589294058625694805490606063729675884839653992735321514315629212636876171499519363523608999887425726764249
c2 =  89525609620932397106566856236086132400485172135214174799072934348236088959961943962724231813882442035846313820099772671290019212756417758068415966039157070499263567121772463544541730483766001321510822285099385342314147217002453558227066228845624286511538065701168003387942898754314450759220468473833228762416
N =  147146340154745985154200417058618375509429599847435251644724920667387711123859666574574555771448231548273485628643446732044692508506300681049465249342648733075298434604272203349484744618070620447136333438842371753842299030085718481197229655334445095544366125552367692411589662686093931538970765914004878579967
delta =  93400488537789082145777768934799642730988732687780405889371778084733689728835104694467426911976028935748405411688535952655119354582508139665395171450775071909328192306339433470956958987928467659858731316115874663323404280639312245482055741486933758398266423824044429533774224701791874211606968507262504865993
'''

思路:

解题关键点:

m1 = m + t1 * delta

m2 = m + t2 * delta

这里涉及到了Franklin-Reiter攻击(相关消息攻击)(relative message attack)

简单来说,相关信息攻击就是**如果两个信息之间存在某种线性关系,并且在相同的n和e下进行RSA加密,那么就有可能恢复出这两个消息**

我直接用的板子

python 复制代码
import binascii
def attack(c1,c2,n,e,i,j):
    PR.<x>=PolynomialRing(Zmod(n))
    # replace a,b,c,d
    delta=93400488537789082145777768934799642730988732687780405889371778084733689728835104694467426911976028935748405411688535952655119354582508139665395171450775071909328192306339433470956958987928467659858731316115874663323404280639312245482055741486933758398266423824044429533774224701791874211606968507262504865993
    g1 = (x+i*delta)^e - c1
    g2 = (x+j*delta)^e - c2

    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()
    return -gcd(g1, g2)[0]
c1 =56853945083742777151835031127085909289912817644412648006229138906930565421892378967519263900695394136817683446007470305162870097813202468748688129362479266925957012681301414819970269973650684451738803658589294058625694805490606063729675884839653992735321514315629212636876171499519363523608999887425726764249
c2 =89525609620932397106566856236086132400485172135214174799072934348236088959961943962724231813882442035846313820099772671290019212756417758068415966039157070499263567121772463544541730483766001321510822285099385342314147217002453558227066228845624286511538065701168003387942898754314450759220468473833228762416
n =147146340154745985154200417058618375509429599847435251644724920667387711123859666574574555771448231548273485628643446732044692508506300681049465249342648733075298434604272203349484744618070620447136333438842371753842299030085718481197229655334445095544366125552367692411589662686093931538970765914004878579967
e =683
delta=93400488537789082145777768934799642730988732687780405889371778084733689728835104694467426911976028935748405411688535952655119354582508139665395171450775071909328192306339433470956958987928467659858731316115874663323404280639312245482055741486933758398266423824044429533774224701791874211606968507262504865993
def a():
    for i in range(0,255):
        print(i)
        for j in range(0,255):
            m1 = attack(c1, c2, n, e,i,j)
            try:
                print(binascii.unhexlify("%x" % int(m1)).decode())
                return 
            except:
                continue
a()

这个需要到sage上运行,运行了快两个小时才出来

这里分享一下sage的安装包:

我用夸克网盘分享了「sage」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。

链接:https://pan.quark.cn/s/f74042154b3d

相关推荐
20岁30年经验的码农9 分钟前
爬虫基础
1024程序员节
秦朝胖子得加钱14 分钟前
Flask
后端·python·flask
幽兰的天空18 分钟前
Python实现的简单时钟
开发语言·python
licy__28 分钟前
计算机网络IP地址分类,子网掩码,子网划分复习资料
1024程序员节
NCU_AI1 小时前
Python 网络爬虫快速入门
python·网络爬虫
幽兰的天空1 小时前
简单的Python爬虫实例
开发语言·爬虫·python
Chris-zz1 小时前
Linux:磁盘深潜:探索文件系统、连接之道与库的奥秘
linux·网络·c++·1024程序员节
JasonYin~1 小时前
《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 模块化基础篇》
1024程序员节
Teamol20202 小时前
求助帖:ubuntu22.10 auto install user-data配置了为何还需要选择语言键盘(如何全自动)
linux·ubuntu·1024程序员节