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

相关推荐
算法小白(真小白)2 小时前
低代码软件搭建自学第二天——构建拖拽功能
python·低代码·pyqt
唐小旭2 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
007php0073 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
Chinese Red Guest3 小时前
python
开发语言·python·pygame
骑个小蜗牛3 小时前
Python 标准库:string——字符串操作
python
黄公子学安全6 小时前
Java的基础概念(一)
java·开发语言·python
程序员一诺6 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
小木_.6 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器
Jiude7 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试