美国大选

程序:

from Crypto.Util.number import *
from secret import p,q
def gcd(a, b):
while b:
a, b = b, a%b
return a flag='DASCTF{********************************}'
e=3
phi = (p-1)*(q-1)
assert gcd(e,phi)==1 d = inverse(e,phi)
print r"Form of vote:{voter}:{votee}! eg: "
print "Yusa:Trump!"
vote = pow(bytes_to_long("Yusa:Trump!"),d,p*q)
print "vote:",vote
try:
yusa = int(raw_input("Your vote: "))
vote = long_to_bytes(pow(yusa,e,p*q)).split(":")
print vote
if vote[-1] == "Trump!":
print flag[:10]
elif vote[-1] == "Biden!":
print flag[10:]
except Exception as e:
print str(e)
exit()

思路:

可以看出这个交互程序中提供了一个加密的机会,而e是已知的,所以可以通过选择明文来得到n的值:

\[c1=m1^3+k_1n \\
c2=m2^3+k_2n \\
n=gcd(c1-m_1^3,c_2-m_2^3)
\]

因为求出的是最大的公约数,所以一定能求出n

实验的程序:

# -*- coding: utf-8 -*-
"""
Created on Tue Oct 19 17:36:27 2021 @author: 01am
""" from Crypto.Util.number import bytes_to_long,long_to_bytes
from gmpy2 import gcd
n=12998510197135204376024977476677066247754836878539929011686148268745119316209020562579171398886840449113325708748228673135311752569187260449619807807903218621065777199171595498055285073001556241300819299111213719824569275786074961700296240844459968460491714678805615009589712788617029938309306389913328704049259197596077475679388746327337019377724684383107233046619031888347065776485290701116620689771500575467431146354734895248116917853679826521686058032549240850391628465710220654255931003952332899029099575800979554751748212159051355321567757716972030886957773638513566062484273620681928826749865617412173047445893
e=3
x=bytes_to_long('当王宝乐醒来的时候,在这梦境迷阵内,已经过去了一天的时间,蛇群的毒没有众人想象中那么剧烈,随行的同学中有人擅长治疗蛇毒,也就使得王宝乐的美好愿望落空。好在随着他的苏醒,名叫周小雅的小白兔对他照顾无微不至,杜敏也罕见的没有与他针锋相对,这就让王宝乐心底舒坦,心里又开始琢磨自己的救人表现,必然会被老师们看到,想来自己这一次考核,应该能加分不少。他唯独郁闷的,就是在之后的几天里,团队众人穿梭丛林,寻找其他同学的路上,柳道斌也不知道吃错了什么药,也许是因为之前的事情愧疚,所以一路上遇到一些小危机,总是抢着带人出手,迅速化解,使得本就虚弱的王宝乐,没有丝毫表现的机会。偏偏又没有出现如蛇群那般大的事件,这就让王宝乐觉得自己一身通天的本领,却没有用武之地,满是郁闷中,只能看着柳道斌在那里不断刷考核分。“这柳道斌再这么下去,说不定隐藏的考核分,就比我高了!”到了最后,王宝乐都焦急了,不过这种情绪没有持续太久,第二天深夜时,在一处一线天的山体下扎营的他们,听到了一声声凄厉的狼嚎。'.encode())
y=bytes_to_long('那声音仿佛可以穿透山石,让所有人都耳骨刺痛,蓦然惊醒,纷纷望去时,立刻看到在他们的前方,那无尽的丛林内亮起了一双双血红色的眼睛。月光下数不尽的凶狼,成扇形包围而来,这些狼群有的在地面飞奔,有的则是跳跃在树枝上,口中发出的狼嚎,目中露出的嗜血,让人望之色变!这一幕,仿佛形成了压抑的狂风,直接就让柳道斌等人面色大变,冷汗淋漓,头皮发麻。“快跑,有狼群!” “是幽骨狼,数不清的幽骨狼!”。一旁的杜敏在经历了蛇群事件后,仿佛一下子就成长了不少,立刻就高呼,让众人进入一线天,利用那里的山堑阻挡狼群。柳道斌脸色变幻不定,最后狠狠一咬牙,面对群狼,并没有立刻撤退,而是召唤同学阻挡拖延时间。小白兔慌乱中扶着王宝乐,身体虽发抖,可却拉着他随人群跑向一线天,只是王宝乐这里,'.encode())
vote = long_to_bytes(pow(x,e,n))
vote2 = long_to_bytes(pow(y,3,n))
c=bytes_to_long(vote)
c2 = bytes_to_long(vote2)
x1=c-pow(x,3)
x2=c2-pow(y,3)
print(gcd(x1,x2))

可以得到n=12998510197135204376024977476677066247754836878539929011686148268745119316209020562579171398886840449113325708748228673135311752569187260449619807807903218621065777199171595498055285073001556241300819299111213719824569275786074961700296240844459968460491714678805615009589712788617029938309306389913328704049259197596077475679388746327337019377724684383107233046619031888347065776485290701116620689771500575467431146354734895248116917853679826521686058032549240850391628465710220654255931003952332899029099575800979554751748212159051355321567757716972030886957773638513566062484273620681928826749865617412173047445893

而下面的过程则是基于n的过大而构建的:

因为n非常大,而e=3又非常的小,所以可以考虑用换一个更小的n1,这样计算出的d满足发送过去的是:

\[a^d\ (mod 2^{54}) \\
\]

然后发过去后,有:

\[a^{ed}\ (mod\ 2^{54} ) \\
\]

但是在传过去之后,服务器程序并不会模\(2^{54}\)。

不过无所谓。因为模数n1取\(2^{54}\),所以小于这个数的部分没有影响。而len(bin(bytes_to_long(b':Biden!')))-2=54,这就意味着无论模不模\(2^{54}\),这个数的后54位(二进制)都是不会变的。所以long_to_bytes转过去,最后就会满足条件。

实验过程:

from Crypto.Util.number import bytes_to_long,getPrime,long_to_bytes
#随机制造一个字符串,满足最后是:Biden!
a=bytes_to_long(b'12312312:Biden!')
n=12998510197135204376024977476677066247754836878539929011686148268745119316209020562579171398886840449113325708748228673135311752569187260449619807807903218621065777199171595498055285073001556241300819299111213719824569275786074961700296240844459968460491714678805615009589712788617029938309306389913328704049259197596077475679388746327337019377724684383107233046619031888347065776485290701116620689771500575467431146354734895248116917853679826521686058032549240850391628465710220654255931003952332899029099575800979554751748212159051355321567757716972030886957773638513566062484273620681928826749865617412173047445893 from gmpy2 import invert
#正常的加解密
c=pow(a,3,2**56)
d=invert(3,2**55)
f=pow(c,d,2**56)
print(long_to_bytes(f)) print(long_to_bytes(pow(pow(a,d,2**56),3,n)))#签名中的先用d后用e >> b':Biden!'
>> b'\x04\x11w`\xb6\xf1\x01\x10\x84q\x98:Biden!'

后面问了一个大佬,他说这个是非预期解,预期解应该是低位逐字节爆破……可惜我不会。

CBC第二课

题目:

from Crypto.Cipher import AES
import os
flag='DASCTF{********************************}'
BLOCKSIZE = 16 def pad(data):
pad_len = BLOCKSIZE - (len(data) % BLOCKSIZE) if len(data) % BLOCKSIZE != 0 else 0
return data + chr(pad_len) * pad_len def unpad(data):
num = ord(data[-1])
return data[:-num] def _enc(data,key,iv):
cipher = AES.new(key,AES.MODE_CBC,iv)
encrypt = cipher.encrypt(pad(data))
return encrypt def enc(data,key):
try:
iv = raw_input("Your iv: ").decode('hex')
cipher = AES.new(key,AES.MODE_CBC,iv)
encrypt = cipher.encrypt(pad(data))
return encrypt
except:
exit() def dec(data,key,iv):
try:
cipher = AES.new(key,AES.MODE_CBC,iv)
encrypt = cipher.decrypt(data)
return unpad(encrypt)
except:
exit() def task():
try:
key = os.urandom(16)
iv = os.urandom(16)
cipher = _enc(flag,key,iv).encode('hex')
print cipher
paintext = raw_input("Amazing function: ").decode('hex')
print enc(paintext,key).encode('hex') backdoor = raw_input("Another amazing function: ")
assert backdoor != cipher if dec(backdoor.decode('hex'),key,iv) == flag:
print flag
else:
print "Wow, amazing results."
except Exception as e:
print str(e)
exit()
if __name__ == "__main__":
task()

思路:

这个题也是一个交互的题,先看解题的要求(服务器输出flag的条件):

  • 先用题目给出的偏移向量iv和加密密钥key加密flag并输出结果cipher
  • 然后给出一个机会用题目给出的key和自己任选的偏移向量iv加密自定的密文paintext,给出加密后的结果
  • 然后要求输入一个与cipher不同的密文,要求该密文解出来的明文(用题目指定的密钥和偏移向量iv)等于flag
  • 当以上条件满足后,输出flag

这个题的关键不在于找到一个解密后与flag相同的密文,而是在于pad和unpad函数。

def pad(data):
pad_len = BLOCKSIZE - (len(data) %
BLOCKSIZE) if len(data) % BLOCKSIZE != 0 else 0
return data + chr(pad_len) * pad_len def unpad(data):
num = ord(data[-1])
return data[:-num]

可以看出,pad函数把最后一块的长度填充到BLOCKSIZE,这样就可以进行和前几块一样的分块加密。但是在加密后还要去除到填充的部分,于是这个pad在填充的时候填充的是填充位数对应的字符,而unpad则读取最后一个字符,转成ASCII码后去掉最后这一填充部分。但这样就会出现一个可以进行长度扩展攻击的机会:对于输出的密文在进行一轮加密,将密文最后一块当做偏移向量(见CBC加密流程图),通过程序开头的flag可以得到最后一块填充了8位,再加上新添加的一块就是16+8=24位。那么用16*chr(24)作为密文,在unpad时可以将新加上的这一块连同之前填充的八位一起去掉,这样就能满足不同的密文解密出来是相同的明文。

所以,从这一道题中,可以学到:不要在pad和unpad中填充有关于明文信息的东西,填入0或者其他什么固定的的东西就好。

CBC第三课

题目:

from Crypto.Cipher import AES
import os
flag='DASCTF{********************************}'
BLOCKSIZE = 16 def pad(data):
pad_len = BLOCKSIZE - (len(data) % BLOCKSIZE) if len(data) % BLOCKSIZE != 0 else 0
return data + "=" * pad_len def unpad(data):
return data.replace("=","") def enc(data,key):
cipher = AES.new(key,AES.MODE_CBC,key)
encrypt = cipher.encrypt(pad(data))
return encrypt def dec(data,key):
try:
cipher = AES.new(key,AES.MODE_CBC,key)
encrypt = cipher.decrypt(data)
return unpad(encrypt)
except:
exit()
def s_2_l(data):
s=[]
for i in range(len(data)//BLOCKSIZE):
s.append(data[BLOCKSIZE*i:BLOCKSIZE*(i+1)])
return s def task():
try:
key = os.urandom(16)
asuy = enc(flag,key)
print asuy.encode('hex') paintext = raw_input("Amazing function(in hex): ")
paintext = paintext.decode('hex')
print enc(paintext,key).encode('hex')
asuy = raw_input("Another amazing function(in hex): ").decode('hex')
yusa = dec(asuy,key) flag_l = s_2_l(flag)
yusa_l = s_2_l(yusa)
for each in yusa_l:
if each in flag_l:
print(r"You're not yusa!")
exit()
print yusa.encode('hex')
except Exception as e:
print str(e)
exit()
if __name__ == "__main__":
task()

思路:

这个题跟上一个题差不多,但是把pad和unpad的缺陷弥补了,所以不能利用上一问中的漏洞了。不过这个题的特殊之处在于向量iv和key是一样的,而且还给了一次解密的机会,这样的话,有:

(借了一个大佬博客的图,地址在参考中有)

  • 我们把加密的明文设为32个0,这样可以减少随机明文对于过程的干扰。
  • 第一轮得到的密文3成为第二轮中的加密向量,而第二轮会得到密文4
  • 因为第二轮输入的明文是16个0,这样异或之后,得到的结果还是密文3
  • 然后把密文4作为输入进行解密,得到一个返回的回显
  • 而这个回显因为长度原因,解密时异或的iv是key,这样的话就会有:密文3^key=回显
  • 而密文3已知,回显也已知,那么就有:key=密文3^回显
  • 然后正常解密即可

参考:

  1. 【20210908 人在寝室坐题从天上来】Crypto方向WP

2021江西省赛赛后总结(Crypto)的更多相关文章

  1. 2021江西省赛线下赛赛后总结(Crypto)

    2021江西省赛线下赛 crypto1 题目: from random import randint from gmpy2 import * from Crypto.Util.number impor ...

  2. 2021 ICPC 江西省赛总结

      比赛链接:https://ac.nowcoder.com/acm/contest/21592   大三的第一场正式赛,之前的几次网络赛和选拔赛都有雄哥坐镇,所以并没有觉得很慌毕竟校排只取每个学校成 ...

  3. 2018年 CCPC 网络赛 赛后总结

    历程:由于只是网络赛,所以今天就三开了.一开始的看题我看了d题,zz和jsw从头尾看起来,发现c题似乎可做,和费马大定理有关,于是和zz一起马上找如何计算勾股数的方法,比较慢的A掉了,而jsw此时看了 ...

  4. 2018年 第43届ACM-ICPC亚洲区域赛(青岛)现场赛 赛后总结

    下了动车后,又颠颠簸簸的在公交车上过了接近一个小时,本来就晕车,于是,到的时候脑子晕死了,而且想吐.可能是没吃早饭的缘故,午饭好好次QWQ. 开幕式 还是第一次在这种环境下参赛,记得以前是看老师发的学 ...

  5. 2016年11月ACM/ICPC亚洲区北京赛赛后总结

    2016年11月12到11月13为期两天的比赛,这是我们这个对第一次去打亚洲区域赛,经过这次比赛,我认识到了自己与别人的差距,也许我们与别人的起点不同,但这不是理由. 这次的比赛12号的热身赛两点开始 ...

  6. HZNU第十二届校赛赛后补题

    愉快的校赛翻皮水! 题解 A 温暖的签到,注意用gets #include <map> #include <set> #include <ctime> #inclu ...

  7. 2018CCPC 吉林现场赛 赛后总结

    一直以来都没有比赛完写总结的习惯,导致前面几次比赛都没有写过总结. 这是我写的第一场总结把,有时间有想法还记得细节的话再把前面几次比赛的总结给补上把. 热身赛: 热身赛的时候,写的比较急想着快点做出题 ...

  8. 11-05-sdust-个人赛赛后随想

    第二次打个人赛 这次居然打秃了,被A题卡的体无完肤.....结果之后转D题心里挂着A题...D题也被卡. 然后第二天不甘心,翘课来机房敲昨天的题,结果两题完全重新敲,都是10分钟左右敲完代码,A题1掉 ...

  9. [luogu#2019/03/10模拟赛][LnOI2019]长脖子鹿省选模拟赛赛后总结

    t1-快速多项式变换(FPT) 题解 看到这个\(f(x)=a_0+a_1x+a_2x^2+a_3x^3+ \cdots + a_nx^n\)式子,我们会想到我们学习进制转换中学到的,那么我们就只需要 ...

随机推荐

  1. 自定义djangorestframework-simplejwt的验证表

    django restframework-simplejwt默认是通过调用django的get_user_model方法来得到验证表的表名,然后再通过查询id来验证是否有这个用户. 当需要自定义用户表 ...

  2. Module 4 - Azure SQL

    1)     Migrate AdventureWorks database from SQL Server instance to Azure SQL using DMA.2)     Update ...

  3. JS 判断上传文件类型

    var video_src_file = $("#video_src_file").val(); var fileTypes = new Array("flv" ...

  4. vue2.0中实现echarts图片下载-----书写中

    由于各个版本浏览器兼容性不一,所以,我们需要一个判断浏览器类型的函数来对不同的浏览器做不同的处理. 获取浏览器版本的函数 // 判断浏览器类型 IEVersion () { let userAgent ...

  5. vue特效网站集锦

    1.17素材网 http://www.17sucai.com/pins/tag/7012.html

  6. FastDFSJava客户端使用

    1.1.java客户端 余庆先生提供了一个Java客户端,但是作为一个C程序员,写的java代码可想而知.而且已经很久不维护了. 这里推荐一个开源的FastDFS客户端,支持最新的SpringBoot ...

  7. 解析HetuEngine实现On Yarn原理

    摘要:本文介绍HetuEngine实现On Yarn的原理,通过阅读本文,读者可以了解HetuEngine如何在资源使用方面融入Hadoop生态体系. 本文分享自华为云社区<MRS HetuEn ...

  8. Hello world.java

    Hello world 1.随便新建一个文件夹,存放源代码 2.新建一个Java文件 文件后缀名为.java Hello.java [注意点]系统可能显示没有后缀名,我们需要手动打开 3.编写代码 p ...

  9. Matlab R2019b安装中的问题

    1.licens文件以及dll文件的放置 MATLAB的安装镜像文件放置在D:\MATLAB,我们MATLAB安装在D:\MATLAB2019B,在激活过程中,我们需要破解文件夹中的license_s ...

  10. 【刷题-LeetCode】307. Range Sum Query - Mutable

    Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...