AES-CBC
https://www.ctfer.vip/problem [安洵杯 2020]easyaes
#!/usr/bin/python from Crypto.Cipher import AES import binascii from Crypto.Util.number import bytes_to_long from flag import flag from key import key iv = flag.strip(b'd0g3{').strip(b'}')#删去头尾指定的字符串 LENGTH = len(key) assert LENGTH == 16#AES128,AES192,AES256(128 位、192 位或 256 位)128位对应的是16个字节,所以部分平台库上,会使用16个字符或者长度为16的字符串来做密码。 hint = os.urandom(4) * 8#os.urandom(n)返回一个有n个byte那么长的一个string;字符串*n->n个字符串 print(bytes_to_long(hint)^bytes_to_long(key)) msg = b'Welcome to this competition, I hope you can have fun today!!!!!!' def encrypto(message): aes = AES.new(key,AES.MODE_CBC,iv) return aes.encrypt(message) print(binascii.hexlify(encrypto(msg))[-32:])#返回二进制数据的16进制的表现形式,从后面截取32个字符 ''' 56631233292325412205528754798133970783633216936302049893130220461139160682777 b'3c976c92aff4095a23e885b195077b66' '''
解题
from Crypto.Util.number import long_to_bytes from Crypto.Util.number import bytes_to_long import binascii, sys from Crypto.Util.strxor import strxor from Crypto.Cipher import AES # -----------get key--------- tmp = 56631233292325412205528754798133970783633216936302049893130220461139160682777 hint = int(str(hex(tmp))[2:10] * 8,16)
#由于hint为32位,key为16位所以他们异或后tmp的高位就是hint的高位
#str() 函数将对象转化为适于人阅读的形式也就是说从hex()到str(hex())表现内容没有改变,2个16进制为一个字节,int(a,16)转16进制 key = long_to_bytes(tmp ^ hint) # ----------get iv----------- msg = b'Welcome to this competition, I hope you can have fun today!!!!!!' msgs = [msg[ii:(ii+16)] for ii in range(0,len(msg),16)]
#将明文分组(常见的以16字节为一组) msgs.reverse()
#倒转msgs IV = binascii.unhexlify('3c976c92aff4095a23e885b195077b66')#??? #decry(key,IV,ms)??? def decry(key,IV,ms): aes=AES.new(key,AES.MODE_ECB) return strxor(aes.decrypt(IV),ms)#strxor(str1,str2)对两个十六进制字符串(用一种十六进制书写的方式来表示一个数值,或一串的数值)进行异或 for ms in msgs: IV=decry(key,IV,ms) print(b'NSSCTF{' + IV+ b'}')
攻击原理:
加密
解密
具体可参考[2020年第三届安洵杯] easyaes writeup - F0und
RSA脚本大多引用自https://lazzzaro.github.io/2020/05/06/crypto-RSA/