美国大选

程序:

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. 物理机异常断电,linux虚拟机系统磁盘mount失败,导致无法启动; kubectl 连接失败

    虚拟机 CentOS 7 挂载文件系统失败 上周五下班前没有关闭虚拟机和物理机, 今天周一开了虚拟机之后,发现操作系统启动失败. 原因跟 这篇文章描述的一模一样. 解决操作系统的文件系统挂载的问题之后 ...

  2. textarea换行符转换

    /** * @description textarea换行符转指定字符 * @param str:要放到textarea的字符串 * @param code:要转换成换行的字符,默认为',' */ e ...

  3. 注意,你所做的 A/B 实验,可能是错的!

    对于 A/B 实验原理认知的缺失,致使许多企业在业务增长的道路上始终在操作一批"错误的 A/B 实验".这些实验并不能指导产品的优化和迭代,甚至有可能与我们的初衷背道而驰,导致&q ...

  4. 解读与部署(三):基于 Kubernetes 的微服务部署即代码

    在基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以及它的 ...

  5. 【原创】美团二面:聊聊你对 Kafka Consumer 的架构设计

    在上一篇中我们详细聊了关于 Kafka Producer 内部的底层原理设计思想和细节, 本篇我们主要来聊聊 Kafka Consumer 即消费者的内部底层原理设计思想. 1.Consumer之总体 ...

  6. visual studio进行机器学习与python编写

    visual studio里的python安装之后自带一个虚拟环境 1.anaconda有些包版本无法到最新. 2.包管理器在安装卸载,强制停止后,包管理器会出问题,一直卸不掉那个包. 在卸载pyth ...

  7. cesium 3dtiles模型单体化点击高亮效果

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. c ...

  8. Servlet虚拟路径匹配规则

    当 Servlet 容器接收到请求后,容器会将请求的 URL 减去当前应用的上下文路径,使用剩余的字符串作为映射 URL 与 Servelt 虚拟路径进行匹配,匹配成功后将请求交给相应的 Servle ...

  9. C++虚函数和静态函数调用方式

    简单情况: #include<iostream> using namespace std; class A { public: virtual void foo() { cout < ...

  10. 使用光盘无网络搭建本地yum源仓库

    目录 一:使用光盘搭建本地yum源 1,按顺序搭建本地yum源 第一步 : 搭载安装光盘 第二步 : 编辑repo yum源文件 第三步 : 检查 yum makecache 注意事项: 一:使用光盘 ...