[ACTF新生赛2020]crypto-aes

文章介绍了在两个黑客竞赛中的加密技术挑战,包括AES的CBC模式、密钥处理和RSA解密方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9[ACTF新生赛2020]crypto-aes

题目信息

from Cryptodome.Cipher import AES
import os
import gmpy2
from flag import FLAG
from Cryptodome.Util.number import *

def main():
    key=os.urandom(2)*16#随机生成一个16字节的密钥
    iv=os.urandom(16)#随机生成一个16字节的向量
    print(bytes_to_long(key)^bytes_to_long(iv))#把秘钥key和向量装换成长整型 并做异或运算
    aes=AES.new(key,AES.MODE_CBC,iv)#使用key和iv创建一个AES加密器,模式为CBC。
    enc_flag = aes.encrypt(FLAG)#使用AES加密器加密FLAG明文,得到密文enc_flag。
    print(enc_flag)
if __name__=="__main__":
    main()

 AES加密器工作原理

AES加密算法——块加密算法,要求输入的数据必须是128bit或者是128bit的整数倍的块,但是因为现实中明文长度是随意的,这时需要某种工作模式能让AES加密任何长度的明文,CBC模式就是其中的一种

CBC工作模式

  1. 将明文划分为多个符合块大小的块p1,p2,...pn
  2. 对第一个块p1与初始化向量iv进行异或,得到p1'
  3. 使用AES加密p1'得到密文块c1
  4. 以此类推,对p2,p3,...,pn异或分别得到密文p1',p2',...,pn',再加密得到密文块c2,c3,...,cn

题解

因为解密需要知道key以及随机向量iv

因为key是按照16字节一个重复,所以高16字节与低16字节是一样的,只要得到其中一半就能得到整个key,key有32个字节,而iv只有16个字节,这意味着什么?

在做异或运算时,只用了key的低16字节与iv做运算,那么out输出的高16字节就是key的高16字节

得到key的高16字节就能得到整个key,那么再利用key的低16字节与out的低16字节做异或运算就能得到iv

得到iv与key,创建AES解密器对密文进行解密,就能得到flag

解密脚本

from Crypto.Util.number import *
from Crypto.Cipher import AES
import os

#转换成为字节类型
out = 91144196586662942563895769614300232343026691029427747065707381728622849079757
out =long_to_bytes(out)
flag_encrypted = b'\x8c-\xcd\xde\xa7\xe9\x7f.b\x8aKs\xf1\xba\xc75\xc4d\x13\x07\xac\xa4&\xd6\x91\xfe\xf3\x14\x10|\xf8p'

#高十六位是key的高十六位 并且key是按照16位进行重复 所以得到高16位就能得到整个key
key = out[:16]*2

#把key的低十六位与out的低十六位做异或就能得到向量iv
iv = bytes_to_long(key[16:])^bytes_to_long(out[16:])
#重新转换成为字节
iv = long_to_bytes(iv)
#创建aes解密器 需要秘钥key 解密模式 还有解密向量iv
aes = AES.new(key,AES.MODE_CBC,iv)
#使用解密器解密
flag = aes.decrypt(flag_encrypted)
print(flag)


[INSHack2019]Yet Another RSA Challenge - Part 1

题目信息

import subprocess
p = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
q = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
flag = int('INSA{REDACTED}'.encode('hex'), 16)

N = int(p,16) * int(q,16)
print N
print '0x'+p.replace('9F','FC')
print pow(flag,65537,N)

可以看到p是中的FC有的是被替换成为9F输出的,那么可以尝试爆破把每种情况都考虑出来,然后根据n能否整除p来判断是否能够正确

解密脚本

import gmpy2


from Crypto.Util.number import long_to_bytes

import binascii
n = 719579745653303119025873098043848913976880838286635817351790189702008424828505522253331968992725441130409959387942238566082746772468987336980704680915524591881919460709921709513741059003955050088052599067720107149755856317364317707629467090624585752920523062378696431510814381603360130752588995217840721808871896469275562085215852034302374902524921137398710508865248881286824902780186249148613287250056380811479959269915786545911048030947364841177976623684660771594747297272818410589981294227084173316280447729440036251406684111603371364957690353449585185893322538541593242187738587675489180722498945337715511212885934126635221601469699184812336984707723198731876940991485904637481371763302337637617744175461566445514603405016576604569057507997291470369704260553992902776099599438704680775883984720946337235834374667842758010444010254965664863296455406931885650448386682827401907759661117637294838753325610213809162253020362015045242003388829769019579522792182295457962911430276020610658073659629786668639126004851910536565721128484604554703970965744790413684836096724064390486888113608024265771815004188203124405817878645103282802994701531113849607969243815078720289912255827700390198089699808626116357304202660642601149742427766381

text=['9F','FC']
for a in text:
    for b in text:
        for c in text:
            for d in text:
                p = "DCC5A0BD3A1" + a + "0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331A" + b + "FD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14" + c + "D2739D76E69283E57DDB11" + d + "531B4611EE3"

                p1 = int(p,16)
                if n%p1==0:
                    pex=p1
                    print(pex)

e = 65537
q = n // pex
d = gmpy2.invert(e, (pex - 1) * (q - 1))
# print(d)
c = 596380963583874022971492302071822444225514552231574984926542429117396590795270181084030717066220888052607057994262255729890598322976783889090993129161030148064314476199052180347747135088933481343974996843632511300255010825580875930722684714290535684951679115573751200980708359500292172387447570080875531002842462002727646367063816531958020271149645805755077133231395881833164790825731218786554806777097126212126561056170733032553159740167058242065879953688453169613384659653035659118823444582576657499974059388261153064772228570460351169216103620379299362366574826080703907036316546232196313193923841110510170689800892941998845140534954264505413254429240789223724066502818922164419890197058252325607667959185100118251170368909192832882776642565026481260424714348087206462283972676596101498123547647078981435969530082351104111747783346230914935599764345176602456069568419879060577771404946743580809330315332836749661503035076868102720709045692483171306425207758972682717326821412843569770615848397477633761506670219845039890098105484693890695897858251238713238301401843678654564558196040100908796513657968507381392735855990706254646471937809011610992016368630851454275478216664521360246605400986428230407975530880206404171034278692756
m = pow(c, d, n)
# print(hex(m))
print(long_to_bytes(m))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值