【moeCTF 题解 -0x04】Crypto
有多少信息熵,就能还原出多少信息
信息熵=
现代密码学知识没学多少,倒是把 Classic Crypto 部分 AK 惹……
【moeCTF 题解】总目录如下:
Classic Crypto
6/6
大帝的征程#1
50points
zbrpgs{p0adh3e_gu3_j0eyq}
有关密码的大帝就是凯撒大帝啦
随便搞一个凯撒密码解密程序:
1 | def encrypt(plaintext): |
输出如下:
1 | zbrpgs{p0adh3e_gu3_j0eyq} |
得到 flag:moectf{c0nqu3r_th3_w0rld}
Ps. 可检测字符是否含有字符串来抑制输出
大帝的征程#2
75points
mpgfxk{j8w05q4_8xk_d7mhqfht}
免费 hint:
table = 'abcdefghijklmnopqrstuvwxyz0123456789'
开了 hint 后就知道是凯撒密码的换表
于是修改上面那个程序如下:
1 | def encrypt(plaintext): |
输出第一行就是 flag:moectf{c0nquer_th3_un1v3rs3}
外面的世界
75points
外面的世界很精彩~
1 mc{i33ny_-n~otR1n_cp1FN}efaFc32Tsuyflag 请准确提交
这个就根据关键词 moectf 直接看出来了,手撕解密:
1 | mc{i33ny_-n~ |
得到 flag:moectf{Rai1F3nc3_3nc2ypT_1s-FunNy~}
其实是不知道栅栏密码
更好的方法:引用吉吉
的WP:
mc{i33ny_-n~otR1n_cp1FN}efaFc32Tsuy
栅栏加密,栏数为12
,注意需要使用正向加密算法因此 flag 为
moectf{Rai1F3nc3_3nc2ypT_1s-FunNy~}
大帝的征程#3
100points
\>@64E7L4_?BF6C0E9b0)s$trN
猜测字符表是 ASCII 可打印字符,一试果然是:
1 | # >@64E7L4_?BF6C0E9b0)s$trN |
得到 flag:moectf{c0nquer_th3_XDSEC}
>@64E7L4_?BF6C0E9b0)s$trN
前 6 位与moectf
做比较,发现差为47
于是编写代码
大帝的征程#维吉尼亚
100points
接下来去哪里呢?
flag 请准确填写。
1 >[Warning] Case Sensitive!
看到附件文本中的pgieqi{k0_ajxW_k-R3zq?}
,应该就是 flag 了,把pgieqi
与moectf
比较,可以大致确定秘钥是xdesc
,所附解密脚本如下:
1 | import string |
根据
A gcjh, A wct, L uspnxwvga.
可能是凯撒大帝的名言I came, I saw, I conquered.
因此根据密码矩阵对密码,对出来是secxd
,也用以解密 flag 得I came, I saw, I conquered. moectf{s0_whaT_s-N3xt?}
因此 flag 为
moectf{s0_whaT_s-N3xt?}
大帝的征程#维吉尼亚 Ex
250points
我听说有人觉得密钥很好猜?
看到附件文本中的ooukot{ig3_oqf1_Ymiedmms_BzVn3_s0w_w0_3csO}
字段,应该就是 flag 了,把ooukot
与moectf
比较,可以确定部分的密钥。根据文章特性和重复字符,可以确定秘钥长度。从而解出一些原文零星的句段,百度这些原文的句段可以明确此文是《终末之诗》,就可知道剩余部分明文,从而得到完整秘钥。附解密脚本如下:
1 | import string |
得到 flag:moectf{th3_rea1_Vigenere_MaYb3_n0t_s0_3asY}
使用重合指数法破解维吉尼亚密码,工具地址,解得密钥为
fdecaqivopzxmfdecaqivopzxm
Crypto
6/10
crypto 入门指北
50points
使用 markdown 可获得最佳观看体验(当然用记事本也能看)
附件如下:
Crypto 入门指北
关于密码学
顾名思义就是研究加密的学科。比如要在 Alice 与 Bob 两人通信过程中,在有 Eve 窃听的情况下,依然保证消息不泄露,这就需要 Alice 用一个加密密钥(类似于开锁的钥匙)对信息加密,而 Bob 将收到的信息用解密密钥解密,这样 Eve 就无法得知通信内容。而凯撒密码就是十分著名的一种加密方式,将字母移位,从而达到加密的目的,凯撒密码属于古典密码,在平台的 Classic Crypto 分类中就有许多这样的密码。但是它们的安全性都基于对加密算法的保护,一旦加密算法暴露,哪怕没有密钥,也能够进行解密。因此,现代密码学要求在加密算法公开的情况下,只要不知道密钥,就无法对消息进行解密。这样的话,仅需要保护一个不算长的密钥即可保护一段信息;即使密钥泄露,换个密钥就能继续用同一个加密算法加密。所以,密码学就是要寻找一个在不知道密钥情况下无法破解的算法。因此,下面这些题目,都会有一个用 python 写的加密脚本,这些都是有漏洞的加密方式,你需要从中找出漏洞,并且在没有密钥的情况下恢复明文。
密码学需要什么基础知识
- 数学基础:密码学是数学的一个应用学科,最早的公钥密码算法 RSA 就是基于数论的,因此学习密码学通常还需要从数论开始学起,公钥密码往后发展的过程中,也逐步用到了线性代数与抽象代数的内容,那些东西由于过难在本次新生赛不会涉及,因此请先从数论开始(除了用于防大佬新生 ak 的 Easy RSA 有用到线性代数的复杂知识,想要钻研的这题的新生请慎重)。其次,最早不是基于数学的块密码,在发展的过程中,也被运用数学的语言来描述,从而更能够更清晰的找到攻击方法。因此,学习密码学会涉及到大量的数学知识,欢迎对数学感兴趣(至少不讨厌)的同学来钻研学习
- 编程基础:现代密码学比古典密码复杂许多,它的加密解密算法不是人能够口算或者笔算出来的东西,因此也需要编程。而密码学由于经常要用到特别大的数字,远超 c 和 c++ 的 long long int 的上限,因此一般使用 python 编写程序。python 是一个较接近自然语言的编程语言,因此容易上手,灵活运用搜索引擎以及网上一些教程很容易学会。
- 英语基础:你有可能会遇到一些需要阅读纯英文文章才能解决的题目,需要有一定的耐心才能看明白。
密码学需要哪些工具
- python
- 两个用的挺多的 python 库:pycryptodome,gmpy2(网上均有安装方法,使用方法也有,也可直接查文档)
- (sagemath)对初学者来说用处不大
如何学习密码学
- 善用搜索引擎
- 在 ctfwiki 的 crypto 分区寻找一些 crypto 的基础知识
我在做题时遇到困难怎么办
- 先去各大搜索引擎轮番搜一遍
- 阅读《提问的智慧》
- 寻找管理员里那个密码 fw 寻求帮助
当然,就算做题没遇到困难,只要对密码学感兴趣,也欢迎去找那个密码 fw 闲聊。并教教他密码学,他可菜了。
crypto 是个比较小众的方向,但也相当有趣。会有很硬核的数学让人想放弃,但坚持下来慢慢搞,一定会有很大收获。
moectf{I_L0Ve_M@th_AnD_CRypT0}
thx~
moectf{I_L0Ve_M@th_AnD_CRypT0}
Stream
100points
Script:
见附件
OutPut:
1
2 1
b'Og9hNAFrCjU9aQ4+C2psLzxpYRE6azw+FmphPgk2EjQBDyw+DWsKIQIPHiwAaBYoOx8wNBU2aGU='
附件:
1 | import base64 |
根据 OutPut 可知道 xor 就是一个字符
那么直接暴力搜索之:
1 | import base64 |
运行脚本得到 flag:moectf{U_Kn0w_How_7o_Break_Stream_Ciphe2}
easycrypto
100points
Try to step in the door of Cryptography and mathematics!
下载附件是一个加密脚本
1 | from FLAG import flag |
啊,是可爱的一元二次方程!就直接解吧,只考虑大的那个解试试看::
1 | def enc(plain): |
运行脚本,竟然直接对了
得到 flag:moectf{Welcome_to_Crypto}
simple_number_theory
150points
Simple integers are also magical
下载附件是一个加密脚本:
1 | flag = b'moectf{xxxxxxxxxxxxxxxxxxx}' |
绞尽脑汁写出解密脚本如下:
1 | import string |
得到 flag:moectf{Integers_@re_W0nderful}
rsa_begin
150points
Do you know RSA?
经过四大关卡,终于可以初窥线代密码学啦,oh_my_RSA
附件中代码如下:
1 | # from gmpy2 import * <-- 注意:这个库我装载不了,官方也好像弃用了,于是我用了其他的库来代替它 下同 |
先学一学啥是 RSA 吧。虽久仰大名,但还不知道其具体原理……
RSA 加密算法是一种非对称加密算法。在公开密钥加密和电子商业中 RSA 被广泛使用。RSA 是 1977 年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA 就是他们三人姓氏开头字母拼在一起组成的。
RSA 算法的可靠性由极大整数因数分解的难度决定。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用 RSA 加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。如今,只有短的 RSA 密钥才可能被强力方式解破。到 2017 年为止,还没有任何可靠的攻击 RSA 算法的方式。
——CTF Wiki
RSA 算法的具体描述如下: [5]
(1)任意选取两个不同的大素数 p 和 q 计算乘积
[5] ;
(2)任意选取一个大整数 e,满足
,整数 e 用做加密钥(注意:e 的选取是很容易的,例如,所有大于 p 和 q 的素数都可用) [5] ;
(3)确定的解密钥 d,满足
,即
是一个任意的整数;所以,若知道 e 和
,则很容易计算出 d [5] ;
(4)公开整数 n 和 e,秘密保存 d [5] ;
(5)将明文 m(m<n 是一个整数)加密成密文 c,加密算法为 [5]
(6)将密文 c 解密为明文 m,解密算法为 [5]
然而只根据 n 和 e(注意:不是 p 和 q)要计算出 d 是不可能的。因此,任何人都可对明文进行加密,但只有授权用户(知道 d)才可对密文解密 [5] 。
——百度百科
再回看题目给的代码,发现它已经把私钥都给我们了,于是根据算法直接解密吧:
1 | from Crypto.Util.number import * |
得到 flag:moectf{uLl_f1Nd_th@t_RsA_1s_1nte2eSt1nG}
啊,神秘的非对称加密
easy 木大定理
200points
听说欧拉定理是 rsa 的基础呢
附件中代码如下:
1 | from gmpy2 import * <-- 注意:这个库我装载不了,官方也好像弃用了,于是我用了其他的库和函数来代替它 下同 |
题目给出了 dec(clist , nlist , e)
的解密算法,但是运行起来特别慢,很难在短时间内得到结果,且主要耗时在phi(p)
上,即计算 1~p 内与 p 互质数的个数,考虑优化这个算法。
根据题目的提示“欧拉定理”,查到相应的知识如下:
欧拉定理:
在数论中,欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。欧拉定理表明,若 n,a 为正整数,且 n,a互质,则:
欧拉函数:
通式:
(其中 p1, p2……pn 为 x 的所有质因数,x 是不为 0 的整数)
定义 φ(1)=1(和 1互质的数 (小于等于 1) 就是 1 本身)。
注意:每种质因数只有一个。
若 n 是质数 p 的 k 次幂,
,因为除了 p 的倍数外,其他数都跟 n 互质。
比如 12=223 那么φ(12)=φ(43)=φ(2^23^1)=(2^2-2^1)*(3^1-3^0)=4
设 n 为正整数,以 φ(n) 表示不超过 n 且与 n 互素的正整数的个数,称为 n 的欧拉函数值
φ:N→N,n→φ(n) 称为欧拉函数。
欧拉函数是积性函数——若 m,n 互质,
特殊性质:当 n 为奇质数时,
, 证明与上述类似。
若 n 为质数则
这样就可以优化phi(p)
,写出更快的phi2(p)
如下:
1 | from Crypto.Util.number import * |
- 注:
gmpy2
库不知道什么原因我装载不了,官方也好像弃用了,于是我用了Crypto.Util.number
、numpy
来代替它,然而invert
好像还是没有,就搞了一个轮子……求助有没有更好的解决方法。
运行得到 flag:moectf{EULEREu1erEule2Eu1erEulerEyoulerEU1e2Mud@MuDaMudamuDaMudaMUDA}
欧拉欧拉欧拉欧拉欧拉欧拉欧拉木大木大木大!
- 为什么木大呢🤔
后面的题就没有做了
未完并不一定待续……