[日常训练] Crypto Training - BUUCTF(一)
序言
本系列为博主在日常训练中对网上各大平台密码学题目的个人题解,题解不介绍具体知识点,不保证最优解法,仅供参考。这一期内容涵盖 BUUCTF 平台训练场中的 Crypto 类别题目,按解题数量从高到低排序,收录了前 1 至 100 道题的解题思路与过程,并根据涉及的密码学知识点进行分类整理。结合个人理解,将密码学类题目按考查重点划分为以下八类:
编码与混淆(Encoding & Obfuscation)
虽不属于严格意义上的“加密”,但在密码题中常作为基础步骤出现。典型形式包括:
- 各类标准编码(Base64、URL 编码)
- 进制转换(二进制、八进制、十六进制等)
- 字符串混淆(兽音译者、JSFuck)
- 简单扰动(XOR 操作、位反转)
传统古典密码(Classical Cryptography)
早期古典密码技术,核心考点为替换与移位机制,常考察手工破解能力。典型形式包括:
- 单表替换(凯撒密码)
- 多表替换(维吉尼亚密码)
- 图形替换(猪圈密码、摩斯电码)
- 换位加密(栅栏密码)
- 混合密码(恩尼格玛机)
现代对称密码(Symmetric Cryptography)
考察现代加密算法实现或使用方式,常涉及密钥管理和模式漏洞。典型形式包括:
- 分组加密(AES、DES)
- 流加密(RC4、Rabbit)
- 模式漏洞(ECB 信息泄露)
- 填充攻击(Padding Oracle)
现代非对称密码(Asymmetric Cryptography)
以 RSA 为代表的公钥密码系统为核心,考察其数学原理与实际应用中的安全隐患。典型形式包括:
- 数学构造型密码(RSA、ECC)
- 参数不安全型(共模攻击、低加密指数攻击)
- 结构缺陷型(Håstad 攻击、CRT 重组)
- 签名验证漏洞(Bleichenbacher 攻击)
哈希与消息认证(Hash / MAC)
涉及哈希函数特性或相关攻击技术。典型形式包括:
- 哈希计算(MD5、SHA1)
- 碰撞攻击(生日攻击)
- 长度扩展攻击(Merkle-Damgård 构造漏洞)
- 爆破攻击(彩虹表)
应用密码学(Applied Cryptography)
更贴近真实场景,重点在于加密协议、密钥管理以及实现漏洞。典型形式包括:
- 参数设计漏洞(Nonce 重用)
- 协议缺陷(TLS/SSL 中间人攻击)
- 物理攻击(侧信道分析、电磁泄露)
自定义构造题(Custom Crypto)
该类题目不依赖标准加密算法,通常由出题者自定义加密逻辑,或将多种密码学知识点巧妙(并非巧妙)融合。需对题目进行逆向与逻辑分析。典型形式包括:
- 算法构造型(结合数据结构与算法、原创加密流程、状态机等)
- 数学建模型(运用数论等基础数学知识构造陷阱)
- 混合型(多种加密知识点融合)
信息隐藏与隐写术(Steganography)
常与 Forensics 交叉, 虽不属于密码学的主流分类,但经常涉及。主要包括图片隐写、音频隐写、文件格式伪装、Zlib/Gzip 压缩混淆。
1. 编码与混淆
1.1 一眼就解密
1.1.1 题目
1 | 下面的字符串解密后便能获得flag:ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30= |
1.1.2 解题思路
Base64 编码
1.1.3 解题脚本
1 | import base64 |
1.2 Url编码
1.2.1 题目
1 | %66%6c%61%67%7b%61%6e%64%20%31%3d%31%7d |
1.2.2 解题思路
Url 编码
1.2.3 解题脚本
1 | from urllib import parse |
1.3 Quoted-printable
1.3.1 题目
1 | =E9=82=A3=E4=BD=A0=E4=B9=9F=E5=BE=88=E6=A3=92=E5=93=A6 |
1.3.2 解题思路
Quoted-printable 编码:使用可打印的 ASCII 字符表示各种编码格式下的字符。它属于 MIME 标准的一部分,常用于电子邮件、HTTP 头信息等场景。
1.3.3 解题脚本
1 | import quopri |
1.4 信息化时代的步伐
1.4.1 题目
1 | # 也许中国可以早早进入信息化时代,但是被清政府拒绝了。附件中是数十年后一位伟人说的话的密文。请翻译出明文(答案为一串中文!) |
1.4.2 解题思路
中文电码(标准中文电码、中文电报码或中文电报明码),最早将汉字转换为电子信号的一种编码方式,用于电报传输中文信息。
最早的汉字电码由威基杰(S.A. Viguer)编制,他借鉴《康熙字典》的部首分类方式,从中挑选 6800 多个常用汉字,编成《电报新书》。随后郑观应将其改编为《中国电报新编》,成为中国最早的汉字电码本。
中文电码表采用四位阿拉伯数字(0001 到 9999)为编码,用于表示最多一万个汉字、字母和符号。汉字按部首优先、笔画次之的顺序排列,字母和符号则被放置在电码表的末尾。
1.4.3 解题脚本
1 | import requests |
1.5 Unencode
1.5.1 题目
1 | 89FQA9WMD<V1A<V1S83DY.#<W3$Q,2TM] |
1.5.2 解题思路
UUencode 编码:Unix 系统下用于通过 uucp 邮件系统传输二进制数据的一种编码格式。
1.5.3 解题脚本
1 | class UUencodeCipher: |
1.6 异性相吸
1.6.1 题目
1 | # key.txt |
1.6.2 解题思路
异或
1.6.3 解题脚本
1 | from Crypto.Util.number import bytes_to_long |
1.7 密码学的心声
1.7.1 题目
1 | 二战时期,某国军官与一个音乐家情妇相好,然而自从那时起,他屡战屡败,敌人似乎料事如神。他也有怀疑过他的情妇,但是他经过24小时观察他的情妇,发现她每天都只是作曲,然后弹奏给战地电台,为士兵们鼓气,并未有任何逾越。那么,间谍到底是谁?这张曲谱是否有猫腻? (答案为一个明文字符串,提交获得的有意义语句通顺字符串即可) |

1.7.2 解题思路
进制转换:八进制数字三个一组转换为 ASCII 码
1.7.3 解题脚本
1 | if __name__ == "__main__": |
1.8 [BJDCTF2020]这是base??
1.8.1 题目
1 | dict:{0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11: 'A', 12: 'B', 13: 'C', 14: 'D', 15: 'E', 16: 'F', 17: 'G', 18: 'H', 19: '7', 20: '8', 21: '9', 22: 'P', 23: 'Q', 24: 'I', 25: 'a', 26: 'b', 27: 'c', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h', 33: 'i', 34: 'j', 35: 'k', 36: 'l', 37: 'm', 38: 'W', 39: 'X', 40: 'Y', 41: 'Z', 42: '0', 43: '1', 44: '2', 45: '3', 46: '4', 47: '5', 48: '6', 49: 'R', 50: 'S', 51: 'T', 52: 'n', 53: 'o', 54: 'p', 55: 'q', 56: 'r', 57: 's', 58: 't', 59: 'u', 60: 'v', 61: 'w', 62: '+', 63: '/', 64: '='} |
1.8.2 解题思路
自定义码表 Base64
1.8.3 解题脚本
1 | import base64 |
1.9 这是什么
1.9.1 题目
1 | # 题目描述 |
1.9.2 解题思路
文件后缀伪造(docx → apk)
JSfuck 前端混淆
1.9.3 解题脚本
1 | from unjsfuck import unjsfuck |
1.10 [BJDCTF2020]signin
1.10.1 题目
1 | welcome to crypto world!! |
1.10.2 解题思路
hex 编码
1.10.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes |
1.11 传感器
1.11.1 题目
1 | 5555555595555A65556AA696AA6666666955 |
1.11.2 解题思路
802.3 曼彻斯特编码(逆序) + 进制转换
1.11.3 解题脚本
1 | def convert_base(num_str: str, from_base: int, to_base: int, zfill: int = 0) -> str: |
1.12 yxx
1.12.1 题目
1 | # 明文.txt |
1.12.2 解题思路
异或
1.12.3 解题脚本
1 | if __name__ == "__main__": |
1.13 [WUSTCTF2020]B@se
1.13.1 题目
1 | 瀵嗘枃锛歁yLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD== |
1.13.2 解题思路
爆破码表 + 自定义码表 Base64
1.13.3 解题脚本
1 | import base64 |
1.14 [AFCTF2018]BASE
1.14.1 题目
附件: attachment.zip
1.14.2 解题思路
十六进制 + base64 + base32 + base16
1.14.3 解题脚本
1 | import base64 |
1.15 鸡藕椒盐味
1.15.1 题目
1 | 公司食堂最新出了一种小吃,叫鸡藕椒盐味汉堡,售价八块钱,为了促销,上面有一个验证码,输入后可以再换取一个汉堡。但是问题是每个验证码几乎都有错误,而且打印的时候倒了一下。小明买到了一个汉堡,准备还原验证码,因为一个吃不饱啊验证码如下:1100 1010 0000 ,而且打印的时候倒了一下。把答案哈希一下就可以提交了。(答案为正确值(不包括数字之间的空格)的32位md5值的小写形式) |
1.15.2 解题思路
海明校验码:每个汉堡 8 块表示数据位为 8 bits,校验位为 4 bits,并且校验位在 $ 2^n $ 的位置。
1.15.3 解题脚本
1 | import hashlib |
1.16 [BJDCTF2020]编码与调制
1.16.1 题目

1 | 密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6 |
1.16.2 解题思路
标准曼彻斯特编码 + 进制转换
1.16.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes |
2. 传统古典密码
2.1 看我回旋踢
2.1.1 题目
1 | synt{5pq1004q-86n5-46q8-o720-oro5on0417r1} |
2.1.2 解题思路
ROT18
2.1.3 解题脚本
1 | class RotCipher: |
2.2 摩丝
2.2.1 题目
1 | .. .-.. --- ...- . -.-- --- ..- |
2.2.2 解题思路
Morse 密码
2.2.3 解题脚本
1 | class MorseCode: |
2.3 变异凯撒
2.3.1 题目
1 | 加密密文:afZ_r9VYfScOeO_UL^RWUc |
2.3.2 解题思路
密文前四位 afZ_
对应明文 flag
,可推测该加密方式为变种凯撒加密:每个字符按递增偏移量依次加密,首位偏移 5 位,之后逐位加 1。
2.3.3 解题脚本
1 | if __name__ == '__main__': |
2.4 篱笆墙的影子
2.4.1 题目
1 | 星星还是那颗星星哟 月亮还是那个月亮 山也还是那座山哟 梁也还是那道梁 碾子是碾子 缸是缸哟 爹是爹来娘是娘 麻油灯呵还吱吱响 点的还是那么丁点亮 哦哦 注意:得到的 flag 请包上 flag{} 提交 |
2.4.2 解题思路
栅栏密码(key = 13)
2.4.3 解题脚本
1 | import math |
2.5 大帝的密码武器
2.5.1 题目
1 | # 密文 |
2.5.2 解题思路
使用凯撒密码解密 FRPHEVGL
,得到有意义单词 SECURITY
。得到偏移量13(ROT13),使用该密钥对 ComeChina 进行加密。
2.5.3 解题脚本
1 | class RotCipher: |
2.6 凯撒?替换?呵呵!
2.6.1 题目
1 | MTHJ{CUBCGXGUGXWREXIPOYAOEYFIGXWRXCHTKHFCOHCFDUCGTXZOHIXOEOWMEHZO} |
2.6.2 解题思路
随机替换密码:一种将明文字母唯一且混乱地替换为不同字母的加密方法,密码字母表完全打乱,短密文需知晓字母对应规则才能解密,长密文则通常借助词频分析破译。使用 http://quipqiup.com/ 词频分析。
2.6.3 解题脚本
1 | import requests |
2.7 萌萌哒的八戒
2.7.1 题目

2.7.2 解题思路
猪圈密码

2.7.3 解题脚本
flag{whenthepigwanttoeat}
2.8 传统知识+古典密码
2.8.1 题目
1 | 小明某一天收到一封密信,信中写了几个不同的年份 |
2.8.2 解题思路
天干地支加密 + 栅栏密码(key=2)+ 凯撒密码(key=21)
2.8.3 解题脚本
1 | import math |
2.9 世上无难事
2.9.1 题目
1 | 以下是某国现任总统外发的一段指令,经过一种奇异的加密方式,毫无规律,看来只能分析了。请将这段语句还原成通顺语句,并从中找到key作为答案提交,答案是32位,包含小写字母。 |
2.9.2 解题思路
随机替换密码:使用 http://quipqiup.com/ 词频分析。
2.9.3 解题脚本
1 | import requests |
2.10 old-fashion
2.10.1 题目
1 | Os drnuzearyuwn, y jtkjzoztzoes douwlr oj y ilzwex eq lsdexosa kn pwodw tsozj eq ufyoszlbz yrl rlufydlx pozw douwlrzlbz, ydderxosa ze y rlatfyr jnjzli; mjy gfbmw vla xy wbfnsy symmyew (mjy vrwm qrvvrf), hlbew rd symmyew, mebhsymw rd symmyew, vbomgeyw rd mjy lxrzy, lfk wr dremj. Mjy eyqybzye kyqbhjyew mjy myom xa hyedrevbfn lf bfzyewy wgxwmbmgmbrf. Wr mjy dsln bw f1_2jyf-k3_jg1-vb-vl_l |
2.10.2 解题思路
随机替换密码:使用 http://quipqiup.com/ 词频分析。
2.10.3 解题脚本
1 | import requests |
2.11 [AFCTF2018]Morse
2.11.1 题目
1 | -..../.----/-..../-..../-..../...--/--.../....-/-..../-..../--.../-.../...--/.----/--.../...--/..---/--.../--.../....-/...../..-./--.../...--/...--/-----/...../..-./...--/...--/...--/....-/...--/...../--.../----./--.../-.. |
2.11.2 解题思路
Morse 密码
2.11.3 解题脚本
1 | class MorseCode: |
2.12 [GXYCTF2019]CheckIn
2.12.1 题目
1 | dikqTCpfRjA8fUBIMD5GNDkwMjNARkUwI0BFTg== |
2.12.2 解题思路
Base64 编码 + ROT47
2.12.3 解题脚本
1 | from base64 import b64decode |
2.13 Cipher
2.13.1 题目
1 | 还能提示什么呢?公平的玩吧(密钥自己找) Dncnoqqfliqrpgeklwmppu |
2.13.2 解题思路
Playfair 密码(key = playfair
)
2.13.3 解题脚本
1 | from typing import Optional, Tuple |
2.14 robomunication
2.14.1 题目
摩斯密码音频:.... . .-.. .-.. --- .-- .... .- - .. ... - .... . -.- . -.-- .. - .. ... -... --- --- .--. -... . . .--.
2.14.2 解题思路
Morse 密码
2.14.3 解题脚本
1 | class MorseCode: |
2.15 [MRCTF2020]古典密码知多少
2.15.1 题目

2.15.2 解题思路
猪圈密码 + 圣堂武士密码 + 标准银河字母 + 栅栏密码(key=3)
2.15.3 解题脚本
1 | # 猪圈密码 + 圣堂武士密码 + 标准银河字母 得到:fgcpflirtuasyon |
2.16 [WUSTCTF2020]佛说:只能四天
2.16.1 题目
1 | # 题目描述.txt |
2.16.2 解题思路
新佛曰密码 + 社会主义核心价值观加密 + 栅栏密码(key=4) + 凯撒密码(key=3) + Base32
2.16.3 解题脚本
1 | # http://www.pcmoe.net/article-89-1.html |
2.17 rot
2.17.1 题目
1 | 破解下面的密文: |
2.17.2 解题思路
ROT-13 + MD5 爆破
2.17.3 解题脚本
1 | import hashlib |
2.18 [MRCTF2020]天干地支+甲子
2.18.1 题目
1 | 得到得字符串用MRCTF{}包裹 |
2.18.2 解题思路
天干地支加密
2.18.3 解题脚本
1 | import gmpy2 |
2.19 [NCTF2019]Keyboard
2.19.1 题目
1 | ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ee www ee yyy eee www w tt ee |
2.19.2 解题思路
九键键盘密码(特点:字母组合中每组字符位数为 1 至 4 位不等)
2.19.3 解题脚本
1 | def T9_password(cipher: str) -> str: |
2.20 [MRCTF2020]vigenere
2.20.1 题目
1 | # cipher.txt |
2.20.2 解题思路
无密钥维吉尼亚密码
2.20.3 解题脚本
1 | import re |
2.21 [MRCTF2020]keyboard
2.21.1 题目
1 | 得到的flag用 |
2.21.2 解题思路
九键键盘密码
2.21.3 解题脚本
1 | def T9_password(cipher: str) -> str: |
2.22 一张谍报
2.22.1 题目
1 | # 家能源总部经过派出卧底长期刺探,终于找到一个潜伏已久的国外内鬼:三楼能源楼管老王。由于抓捕仓促,老王服毒自尽了。侦查部门搜出老王每日看的报纸原来是特制的情报。聪明的你能从附件的报纸中找出情报么?flag是老王说的暗号。(由于老王的线人曾今做的土匪,所以用的行话) |
2.22.2 解题思路
单表替换密码:单表替换,可见两段重复新闻内容略有差异,对比提取不同之处组成翻译表,还原明文。
2.22.3 解题脚本
1 | if __name__ == "__main__": |
2.23 [AFCTF2018]Vigenère
2.23.1 题目
1 | #include <stdio.h> |
2.23.2 解题思路
无密钥维吉尼亚密码
2.23.3 解题脚本
1 | import re |
2.24 [AFCTF2018]Single
2.24.1 题目
1 | #include <bits/stdc++.h> |
2.24.2 解题思路
随机替换密码:使用 http://quipqiup.com/ 词频分析。
2.24.3 解题脚本
1 | import requests |
2.25 [UTCTF2020]basic-crypto
2.25.1 题目
1 | 01010101 01101000 00101101 01101111 01101000 00101100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110111 01100101 00100000 01101000 01100001 01110110 01100101 00100000 01100001 01101110 01101111 01110100 01101000 01100101 01110010 00100000 01100010 01101100 01101111 01100011 01101011 00100000 01101111 01100110 00100000 01110100 01100101 01111000 01110100 00101100 00100000 01110111 01101001 01110100 01101000 00100000 01110011 01101111 01101101 01100101 00100000 01110011 01101111 01110010 01110100 00100000 01101111 01100110 00100000 01110011 01110000 01100101 01100011 01101001 01100001 01101100 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00101110 00100000 01000011 01100001 01101110 00100000 01111001 01101111 01110101 00100000 01100110 01101001 01100111 01110101 01110010 01100101 00100000 01101111 01110101 01110100 00100000 01110111 01101000 01100001 01110100 00100000 01110100 01101000 01101001 01110011 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01101001 01110011 00111111 00100000 00101000 01101000 01101001 01101110 01110100 00111010 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01101100 01101111 01101111 01101011 00100000 01100011 01100001 01110010 01100101 01100110 01110101 01101100 01101100 01111001 00101100 00100000 01111001 01101111 01110101 00100111 01101100 01101100 00100000 01101110 01101111 01110100 01101001 01100011 01100101 00100000 01110100 01101000 01100001 01110100 00100000 01110100 01101000 01100101 01110010 01100101 00100000 01101111 01101110 01101100 01111001 00100000 01100011 01101000 01100001 01110010 01100001 01100011 01110100 01100101 01110010 01110011 00100000 01110000 01110010 01100101 01110011 01100101 01101110 01110100 00100000 01100001 01110010 01100101 00100000 01000001 00101101 01011010 00101100 00100000 01100001 00101101 01111010 00101100 00100000 00110000 00101101 00111001 00101100 00100000 01100001 01101110 01100100 00100000 01110011 01101111 01101101 01100101 01110100 01101001 01101101 01100101 01110011 00100000 00101111 00100000 01100001 01101110 01100100 00100000 00101011 00101110 00100000 01010011 01100101 01100101 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01100011 01100001 01101110 00100000 01100110 01101001 01101110 01100100 00100000 01100001 01101110 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01110100 01101000 01100001 01110100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110100 01101000 01101001 01110011 00100000 01101111 01101110 01100101 00101110 00101001 00001010 01010100 01101101 01010110 00110011 01001001 01000111 01001110 01101111 01011001 01010111 01111000 01110011 01011010 01010111 00110101 01101110 01011010 01010011 01000101 01100111 01010001 00110010 01000110 01110101 01001001 01001000 01101100 01110110 01100100 01010011 01000010 01101101 01100001 01010111 01100100 00110001 01100011 01101101 01010101 01100111 01100010 00110011 01010110 00110000 01001001 01001000 01100100 01101111 01011001 01011000 01010001 01101110 01100011 01111001 01000010 01101110 01100010 00110010 01101100 01110101 01011010 01111001 01000010 01110110 01100010 01101001 01000010 01101111 01011010 01011000 01001010 01101100 01010000 01111001 01000010 01001010 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100011 01111001 01000010 01110011 01100001 01010111 01110100 01101100 01001001 01001000 01010010 01101111 01011010 01010011 01000010 01110011 01011010 01011000 01010010 00110000 01011010 01011000 01001010 01111010 01001001 01000111 01000110 01111001 01011010 01010011 01000010 01111010 01100001 01000111 01101100 01101101 01100100 01000111 01010110 01101011 01001001 01000111 01001010 00110101 01001001 01001000 01001110 01110110 01100010 01010111 01010101 01100111 01011001 00110010 00111001 01110101 01100011 00110011 01010010 01101000 01100010 01101110 01010001 01110101 01001001 01000011 01101000 01101111 01100001 01010111 00110101 00110000 01001111 01101001 01000010 00110101 01100010 00110011 01010101 01100111 01100010 01010111 01101100 01101110 01100001 01001000 01010001 01100111 01100100 00110010 01000110 01110101 01100100 01000011 01000010 00110000 01100010 01111001 01000010 01111010 01100100 01000111 01000110 01111001 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100001 01010111 00110101 01101110 01001001 01001000 01010110 01110111 01001001 01000110 01001010 01110110 01100010 01010111 01000110 01110101 01001001 01001000 01000010 01101100 01100010 00110011 01000010 01110011 01011010 01010011 01101011 01110101 01000011 01101101 01110100 00110010 01011001 01101110 01001110 01111000 01100011 01101101 01010001 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01100100 01101001 01100010 01111001 01000010 01110010 01100100 01101110 01100100 00110101 01011001 00110010 01010001 01100111 01011010 01001000 01001010 01110110 01011001 01101101 00111000 01101000 01001001 01000110 01101000 00110101 01011010 01111001 01000010 01110111 01100101 01010111 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 01111010 01100101 01000111 01110100 00110010 01001001 01000011 01101000 01110010 01100101 01000111 00110100 01100111 01100100 00110010 01110100 01110000 01100010 01000111 00111000 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01001010 01110010 01011001 01101101 00110101 01110110 01011001 00110010 01010001 01110101 01001100 01101001 00110100 01110000 01001001 01001000 01110000 01110010 01011001 01101101 01010001 00110110 01001001 01000111 01110011 01100111 01011001 00110010 01010110 01110011 01011001 00110010 01010010 01111010 01011010 01000111 01010110 01101011 01100011 00110011 01101100 00110100 01001001 01000111 00110001 01111010 01100101 01101110 01001010 01110110 01011001 01101001 00110100 01100111 01010101 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110011 01001110 00110100 01100011 01010011 01000010 01101011 01100010 00110010 01101000 01101011 01001100 01000011 01000010 01010100 01001010 00110010 01011010 01110110 01001001 01000111 01010010 01110010 01100100 01010111 00111001 00110100 01001001 01001000 01100100 01110000 01001001 01001000 01100100 01110110 01011001 00110010 01001110 01110010 01100011 01010111 00111000 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001010 01110110 01100101 01101110 01011010 01110010 01100010 01010111 00111001 01110101 01001001 01000111 00111001 01101101 01100010 00110010 01001010 01110000 01001001 01000111 01110100 00110010 01100101 01101110 01001010 01110010 01100010 01000111 00111001 01101011 01100011 00110010 00110000 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01001001 01000111 01100100 01111010 01011010 01001000 01001001 01100111 01100001 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 01111001 01000010 01101011 01100101 01010011 01000010 01110010 01001001 01000111 00110101 01111010 01100011 01001000 01000010 01110110 01011001 01101101 00111001 00110100 01011010 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01001100 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01100101 01000011 01000010 01110010 01011001 01111001 01000010 01110010 01001001 01000111 01001110 01101100 01100010 01000111 01001110 01101011 01100011 00110010 01010010 01101100 01011010 01001000 01001110 00110101 01100101 01000011 01000010 01110100 01100011 00110011 01110000 01111001 01100010 00110010 01001001 01110101 01001001 01000101 00110001 01110010 01100101 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100011 01001000 01001110 00110100 01100010 01101001 01000010 01101011 01100011 01101101 00111000 01100111 01100011 01001000 01001110 00110100 01100001 00110011 01011001 01100111 01100011 01001000 01011010 01110010 01100011 01010100 00111000 01100111 01100011 01101110 01001110 00110100 01011010 01000100 01101111 01100111 01010010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100100 01101101 01110100 01111000 01001001 01001000 01001110 01101010 01001001 01001000 01000110 00110101 01100011 00110011 01101000 01111000 01001001 01000111 01010010 00110101 01001001 01000111 01111000 01110110 01001001 01001000 01101100 01110111 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100101 01010111 01001010 00110011 01100001 00110010 01010001 01100111 01011010 01010111 01010010 01110111 01100100 01101101 01110100 01111000 01100101 01111001 00110100 01110101 01001100 01101110 00110000 01100111 01001100 01010011 01000010 01101110 01100011 01101110 01001110 01110100 01100011 01101001 01000010 00110011 01100010 00110010 01110100 00110100 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01001000 01001110 01110111 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01101010 01100010 00110010 00111000 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01000010 00110110 01100001 00110010 01010010 01101011 01100010 00110010 01001010 00110100 01001100 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101110 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 00110010 01001101 01100111 01100011 01001000 01101100 01101001 01001001 01000111 01010101 01110011 01001001 01000111 01010001 01110011 01001001 01001000 01000001 01110011 01001001 01001000 01011001 01100111 01100001 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01001000 01000101 01100111 01100001 00110010 01001010 01110110 01001100 01101001 01000010 01001010 01100101 01010111 01010101 01100111 01100010 01010111 01110100 00110100 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01100100 00110101 01011001 01101110 01010101 01100111 01100101 01010111 01010110 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01101001 01100010 00110011 01100100 01110010 01100011 00110011 01101000 01111010 01100101 01001000 01000101 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01011001 01111001 01000010 01110011 01100001 01010011 01000010 01101001 01100010 00110011 01110000 00110010 01100001 00110010 00110001 01111010 01100101 01001000 01000101 01100111 01011010 01001000 01001010 01110110 01100100 01111001 01000010 01110010 01100101 01000111 00110100 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001010 01101001 01100011 00110011 01101000 01111000 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01111010 01100101 01000011 01000010 01101011 01100011 01101101 00111000 01100111 01010100 00110011 01101000 01111000 01100100 01101110 01001110 01101010 01100011 01101001 01000010 00110010 01100001 00110011 01101000 01111000 01011010 01010111 01110100 01111000 01100010 01111001 00110100 01100111 01010011 00110011 01101000 00110101 01011010 01001000 01001010 01110110 01011001 01101001 01000010 01111000 01011001 01101101 00111001 01110010 01011010 01000011 01000010 00110011 01100010 00110010 01010010 01111001 01100101 01010111 00110100 01100111 01100011 00110010 01001101 01100111 01011010 01001000 01101011 01100111 01011010 01010111 01001110 01110110 01001001 01001000 01000010 01101001 01100010 00110010 01000110 01101100 01100010 00110011 01101000 01110100 01100001 01010011 01000010 01110010 01100101 01000111 01110100 00110010 01100001 01010111 01001110 01111010 01011001 01111010 01101111 01100111 01011010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000011 01100100 01110110 01001010 01111001 01000010 01101010 01100011 01101110 01101100 01101110 01011001 01111001 01000010 01101100 01100101 01101001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01001000 01101100 01110111 01011010 01000111 00111001 00110100 01001001 01001000 01001110 00110100 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110010 01100100 01101110 01110000 01111001 01100001 00110010 01111000 01110110 01011010 01000011 01110111 01100111 01011001 00110011 01101011 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01100100 01101010 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01010010 01111001 01100010 01111001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01010010 01110110 01100001 01000111 01010001 01110011 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110010 00111001 01110101 01001001 01000111 01111000 01110000 01001001 01000011 01100100 01101011 01001010 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001110 00110101 01001001 01001000 01101100 00110100 01001100 01101001 01000010 01011010 01100101 01000111 00110001 01110110 01001001 01000111 01101100 00110101 01011010 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01001001 01000111 01110011 01100111 01100011 01000111 00111001 01101110 01001001 01000111 00110001 01111001 01100001 00110010 01001010 01110010 01100010 01010111 01010010 01110110 01011001 01101101 01001101 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01110100 01100001 00110011 01100111 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01001010 01110110 01011001 00110010 01010001 01100111 01100101 01011000 01000001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01100100 00110101 01011001 01101101 00110101 01101010 01001001 01000111 01111000 01110010 01011001 00110010 00111001 01110101 01001001 01001000 01101100 00110100 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01001110 01111001 01100101 01010111 01100011 01100111 01011010 01011000 01101111 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000101 00111001 00110100 01100011 01011000 01011010 01111010 01011001 00110011 01001001 01100111 01100100 01101101 01110100 00110100 01100011 01010111 01010110 01110010 01100011 01010111 00111000 01110101 01000011 01101110 01001010 01101110 01100001 01000111 00110101 00110100 01100011 00110010 01010010 01101101 01100101 01011000 01001110 01101011 01100100 01000111 01100100 01101111 01100100 01010011 01000101 01100111 01100011 01010111 01100100 01101101 01001001 01000111 01101100 01111010 01011001 01010111 01110011 01100111 01011001 00110011 01010010 01101111 01100100 01001000 01010110 01110000 01100001 00110010 01010101 01100111 01011010 01000111 01101100 01110010 01001001 01001000 01110000 01110010 01100010 01101110 01010010 01101111 01100001 01000111 01110100 00110100 01001001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01011010 00110010 00110101 00110100 01100011 00110010 01111000 01110000 01100011 01010011 01000010 01111001 01100001 01011000 01001110 00110101 01100101 01010111 01110100 01101111 01100010 01101101 01110011 01110101 01001001 01000111 01101100 01110010 01100101 01000111 01110011 01100111 01100100 01001000 01010101 01100111 01100011 01111001 01000010 01101010 01100101 01011000 01001110 01110101 01001001 01000111 01001110 01101110 01100101 01000011 01000010 01111010 01100101 01011000 01101011 01100111 01100011 01010111 01100100 01101101 01100101 01000011 01000010 01110000 01100011 00110011 01101000 01101100 01001001 01000111 01110100 01101010 01011001 00110010 01100100 00110100 01011010 01001000 01010101 00110110 01001001 01000111 01011010 01101011 01011001 00110011 01101100 01111010 01100010 01101110 01110100 01101111 01001101 01001000 01011010 01100110 01011010 01000111 01101011 00110000 01011010 01001000 01010110 01100110 01100100 01101101 01101011 00110000 01011010 01000110 00111001 00110000 01011000 00110011 01001001 00110000 01100101 01011000 01101100 01100110 01100011 01101110 01101000 01111000 01100010 01000111 01010001 01110111 01100110 01010011 00110100 01100111 01100011 01010111 01100100 01101101 01001001 01001000 01011010 00110000 01100101 01011000 01101011 01100111 01011001 00110011 01010010 01101111 01011010 01010011 01000010 01101011 01100001 01011000 01001110 01101011 01001001 01001000 01001101 01100111 01100101 01010111 01100100 01101011 01001001 01000111 01100100 01101010 01001001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01011010 00110010 00110101 00110100 01100011 00110010 01111000 01110000 01100011 01010011 01000010 00110000 01100100 01010011 01000010 01110111 01011010 01101110 01010110 01101011 01001001 01001000 01110000 01101101 01100100 01001000 01101100 01101100 01100100 01000111 01101000 01110101 01001001 01000111 01100100 01101010 01011001 01111001 01000010 01101011 01100001 01011000 01010010 00110001 01001001 01001000 01010110 01101110 01100101 01000111 01010001 01100111 01011010 00110010 01001101 01100111 01100101 01101110 01001110 00110001 01100100 01001000 01001001 01100111 01011001 01101101 01101000 01101110 01100100 01101110 01101100 01110010 01011010 01010111 00110101 01110010 01001100 01000011 01000010 01111010 01100001 01000111 01010101 01100111 01100100 01000111 01010001 01100111 01100101 01000111 01110100 01111010 01100101 01011000 01101100 01111000 01001001 01001000 01010010 00110001 01001001 01000111 01101000 01101110 01011010 01000011 01000010 00110001 01011010 01111001 01000010 00110110 01100011 00110010 01010101 01100111 01100011 00110010 01001110 01101011 01100001 00110011 01100111 01100111 01100011 00110011 01101100 00110101 01001100 01101001 01000010 01110000 01011010 00110010 01111000 01110010 01001001 01001000 01000110 01101110 01011010 01101001 01000010 01110010 01100001 01001000 01000010 01101110 01100011 01010111 01110100 01101100 01001001 01000111 01010010 01110000 01100001 01111001 01000010 01111001 01100001 01011000 01001110 00110101 01100101 01010111 01110100 01101111 01100010 01101101 01110011 01101000 |
2.25.2 解题思路
二进制编码 + Base64 编码 + Avocat 密码(key=10) + 随机替换密码
2.25.3 解题脚本
1 | from base64 import b64decode |
2.26 四面八方
2.26.1 题目
1 | 四方门主东方青木看着四面八方涌过来的极客,非常震惊,转头便进入了祖祠中的地下室,发现这丫传自唐朝的密室还设计了英文密码。旁边的石头上(附件中有拓本)刻着密码和密文,大家快帮助门主解出密码(答案为一串通顺语义字符串) |
2.26.2 解题思路
四方密码
2.26.3 解题脚本
1 | import re |
2.27 [NPUCTF2020]Classical Cipher
2.27.1 题目
1 | # key.txt |

2.27.2 解题思路
Atbash 密码 + 变种猪圈密码 + 古埃及象形文字
2.27.3 解题脚本
1 | class AtBashCipher: |
2.28 [BJDCTF2020]Polybius
2.28.1 题目
1 | 密文:ouauuuoooeeaaiaeauieuooeeiea |
2.28.2 解题思路
hint(base64):The length of this plaintext: 14
Polybius Square Cipher(棋盘密码):利用波利比奥斯方阵进行加密的密码方式,密文长度是明文长度的两倍,密文只有五种字符。
2.28.3 解题脚本
1 | import itertools |
2.29 [ACTF新生赛2020]crypto-classic1
2.29.1 题目
1 | # hint.txt |
2.29.2 解题思路
电脑键盘密码:取每组字母环绕所包围的中心字母作为明文。根据这种规则,得到压缩包密码为:circle。
解压得到:SRLU{LZPL_S_UASHKXUPD_NXYTFTJT}
,根据压缩名字提示维吉尼亚密码。
2.29.3 解题脚本
1 | import string |
2.30 浪里淘沙
2.30.1 题目
1 | 我有密集恐惧症,所以大家自求多福吧,把获得的单词连在一起提交即可。(我这里有一串数字:4,8,11,15,16) |
2.30.2 解题思路
词频分析:获取每个单词出现的频率,升序排列,最后将排在 4,8,11,15,16 的单词。
2.30.3 解题脚本
1 | if __name__ == "__main__": |
3. 现代对称密码
3.1 Rabbit
3.1.1 题目
1 | U2FsdGVkX1/+ydnDPowGbjjJXhZxm2MP2AgI |
3.1.2 解题思路
Rabbit 流密码:一种高速流加密算法,2003 年首次在 FSE 研讨会上提出。它使用 128 位密钥和 64 位初始化向量(IV),核心是一种能每轮输出 128 位密钥流的位流生成器,用于加密等长明文。Rabbit 设计轻量、运算高效,特别适用于资源受限设备。
3.1.3 解题脚本
1 | var CryptoJS = CryptoJS || function (n, l) { |
3.2 [ACTF新生赛2020]crypto-aes
3.2.1 题目
1 | from Cryptodome.Cipher import AES |
3.2.2 解题思路
参数设置不当、高位泄露
AES 32 字节密钥与 16 字节 IV 进行异或,高 16 字节泄露。且密钥只有 2 字节的熵,后面是重复 16 次。可以求出 key 和 iv。
3.2.3 解题脚本
1 | from Crypto.Cipher import AES |
4. 现代非对称密码
4.1 RSA
4.1.1 题目
1 | 在一次 RSA 密钥对生成中,假设 p=473398607161,q=4511491,e=17 |
4.1.2 解题思路
标准 RSA 解密
$ \begin{gathered}
\phi(N)=(p-1)*(q-1) \
d=e^{-1} \mod \phi(N)
\end{gathered} $
4.1.3 解题脚本
1 | from Crypto.Util.number import inverse |
4.2 rsarsa
4.2.1 题目
1 | Math is cool! Use the RSA algorithm to decode the secret message, c, p, q, and e are parameters for the RSA algorithm. |
4.2.2 解题思路
标准 RSA 解密
4.2.3 解题脚本
1 | from math import prod |
4.3 RSA1
4.3.1 题目
1 | p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 |
4.3.2 解题思路
$ dp、dq $ 泄露
已知 $ p、q、dp、dq、c $ 求明文 $ m $
4.3.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes, GCD, inverse |
4.4 RSA3
4.4.1 题目
1 | c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361 |
4.4.2 解题思路
RSA 的共模攻击
$ m 、n $ 相同;$ e 、 c $ 不同,且 $ e_1 $ 和 $ e_2 $ 互质。
4.4.3 解题脚本
1 | from gmpy2 import gcdext |
4.5 RSA2
4.5.1 题目
1 | e = 65537 |
4.5.2 解题思路
$ dp、dq $ 泄露
已知 $ dp\ (dq)、n、e、c $,求明文 $ m $
4.5.3 解题脚本
1 | from Crypto.Util.number import inverse, long_to_bytes |
4.6 RSA
4.6.1 题目
1 | # flag.enc |
4.6.2 解题思路
提取公钥 + 大素数分解 + 标准 RSA 解密
4.6.3 解题脚本
1 | import rsa |
4.7 RSAROLL
4.7.1 题目
1 | # 题目.txt |
4.7.2 解题思路
前两个是 $ (n,e) $,后面是密文分块,按行依次解密。
4.7.3 解题脚本
1 | import re |
4.8 Dangerous RSA
4.8.1 题目
1 | littlE littlE RSA Big Big Dangerous |
4.8.2 解题思路
RSA 低公钥指数攻击
特点:$ e $ 很小,$ m $ 很小,$ n $ 很大
如果明文很小,$ e $ 次方后仍小于模数 $ n(m^e \lt n )$,则直接对密文开 $ e $ 次方即可得到明文。
如果明文 $ e $ 次方结果比 $ n $ 大($ m^e \gt n $),则有 $ C=m^e+k \cdot n $,尝试爆破 $ k $,如果找到一个 $ k $ 能开 $ e $ 次方根,则找到明文。
4.8.3 解题脚本
1 | import itertools |
4.9 [HDCTF2019]basic rsa
4.9.1 题目
1 | import gmpy2 |
4.9.2 解题思路
标准 RSA 解密
4.9.3 解题脚本
1 | from math import prod |
4.10 [GUET-CTF2019]BabyRSA
4.10.1 题目
1 | p+q : 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea |
4.10.2 解题思路
已知 $ p+q $ 和 $ (p+1) \cdot (q+1) $ 可求 $ n $,标准 RSA 解密
4.10.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes |
4.11 rsa2
4.11.1 题目
1 | N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471 |
4.11.2 解题思路
大素数分解 $ n $,已知 $ n、e $ 求 $ d $
4.11.3 解题脚本
1 | import hashlib |
4.12 RSA5
4.12.1 题目
1 | m = xxxxxxxx |
4.12.2 解题思路
模不互素:存在两个或更多模数 $ n $ 且其中至少一对 $ n_i $ 和 $ n_j $ 不互质。
4.12.3 解题脚本
1 | import re |
4.13 [NCTF2019]childRSA
4.13.1 题目
1 | from random import choice |
4.13.2 解题思路
Smooth 光滑攻击:Pollard’s p−1 攻击
已知 $ a $ 与 $ p $ 互质,且 $ p $ 为素数,根据费马小定理有:
$$
a^{p-1} \equiv 1 \pmod{p}
$$
设 $ p - 1 = m_1 \cdot m_2 \cdot m_3 \cdots m_n $,且 $ \max(m_1, m_2, m_3, \ldots, m_n) \le B $,则有:
$$
p - 1 \mid B!
$$
进一步推出:
$$
a^{B!} \equiv 1 \pmod{p}
$$
即:
$$
a^{B!} - 1 = k p
$$
又因为 $ N = p \cdot q $,所以:
$$
\gcd(a^{B!} - 1,\ N) = p
$$
4.13.3 解题脚本
1 | from math import prod |
4.14 [HDCTF2019]bbbbbbrsa
4.14.1 题目
1 | from base64 import b64encode as b32encode |
4.14.2 解题思路
RSA 低公钥指数攻击:爆破小指数 $e$
4.14.3 解题脚本
1 | import itertools |
4.15 [BJDCTF2020]RSA4
4.15.1 题目
1 | N = 331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004 |
4.15.2 解题思路
低加密指数广播攻击(Håstad’s Broadcast Attack):$ m、e $ 相同,$ e = 3 $,多组加密的 $ n $ 和 $ c $
进制转换(五进制改为十进制)
4.15.3 解题脚本
1 | from gmpy2 import iroot, mpz |
4.16 [BJDCTF2020]rsa_output
4.16.1 题目
1 | {21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111,2767} |
4.16.2 解题思路
共模攻击:若干次加密,$ e $ 不同,$ N $ 相同,$ m $ 相同
4.16.3 解题脚本
1 | from gmpy2 import gcdext |
4.17 [BJDCTF2020]RSA
4.17.1 题目
1 | from Crypto.Util.number import getPrime,bytes_to_long |
4.17.2 解题思路
模不互素:存在两个或更多模数 $ n $ 且其中至少一对 $ n_i $ 和 $ n_j $ 不互质
RSA 低公钥指数攻击:爆破小指数 $ e $
4.17.3 解题脚本
1 | from math import prod |
4.18 [WUSTCTF2020]babyrsa
4.18.1 题目
1 | c = 28767758880940662779934612526152562406674613203406706867456395986985664083182 |
4.18.2 解题思路
大素数分解
4.18.3 解题脚本
1 | import requests |
4.19 [ACTF新生赛2020]crypto-rsa3
4.19.1 题目
1 | from flag import FLAG |
4.19.2 解题思路
p、q 参数设置不当(近似攻击)
$ p $ 和 $ q $ 相邻,$ n^\frac{1}{2} $ 近似等于 $ p $,向下遍历求出 $ p $
4.19.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes, inverse |
4.20 [GWCTF 2019]BabyRSA
4.20.1 题目
1 | import hashlib |
4.20.2 解题思路
p、q 参数设置不当(近似攻击):$ p $ 和 $ q $ 相邻,$ n^\frac{1}{2} $ 近似等于 $ p $,向下遍历求出 $ p $,进而求出 $ c_1 、 c_2 $。
已知 $ F_1 + F_2 $ 和 $ F_1^3 + F_2^3 $ 可求 $ F_1 、 F_2 $,证明:
$$
\begin{gathered}
F_1^3+F_2^3=(F_1+F_2)(F_1^2-F_1F_2+F_2^2)
\
将\ F_1+F_2=S\ 代入,得:T=S\cdot(F_1^2-F_1F_2+F_2^2)
\
\because F_1^2+F_2^2=(F_1+F_2)^2-2F_1F_2=S^2-2F_1F_2
\
\therefore T=S\cdot[(S^2-2F_1F_2)-F_1F_2]=S\cdot(S^2-3F_1F_2)=S^3-3S\cdot F_1F_2
\
\because S\neq0 \quad \therefore F_1F_2=\frac{S^3-T}{3S}
\
已知\ F_1 + F_2 = S\ 和\ F_1 F_2 = \frac{S^3-T}{3S}=P
\
F_1\ 和\ F_2\ 是一元二次方程的根:x^2 - Sx + P = 0
\
根据求根公式:x = \frac{S \pm \sqrt{S^2 - 4P}}{2}
\
得:F_1, F_2 = \frac{S \pm \sqrt{\frac{4T - S^3}{3S}}}{2}
\end{gathered}
$$
4.20.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes, inverse |
4.21 SameMod
4.21.1 题目
1 | {6266565720726907265997241358331585417095726146341989755538017122981360742813498401533594757088796536341941659691259323065631249,773} |
4.21.2 解题思路
共模攻击
ASCII 码解码得 flag
4.21.3 解题脚本
1 | from gmpy2 import gcdext, mpz |
4.22 [AFCTF2018]你能看出这是什么加密么
4.22.1 题目
1 | p=0x928fb6aa9d813b6c3270131818a7c54edb18e3806942b88670106c1821e0326364194a8c49392849432b37632f0abe3f3c52e909b939c91c50e41a7b8cd00c67d6743b4f |
4.22.2 解题思路
标准 RSA 解密
4.22.3 解题脚本
1 | from math import prod |
4.23 [NCTF2019]babyRSA
4.23.1 题目
1 | from Crypto.Util.number import * |
4.23.2 解题思路
p、q 参数设置不当(近似攻击)
已知 $ e $、$ d $、$ \phi(n) $ 或 $ n $ 的范围,求 n:
$$
\begin{gathered}
\because ed \equiv 1 \pmod {\phi(n)} \
\therefore ed=k \cdot \phi(n)+1
\end{gathered}
$$
$ ed-1 $ 长度为 2064 位,范围在 $2^{2063} \leq ed-1 \lt 2^{2064}$、并且 $\phi(n)$ 长度为 2048 位,范围在 $ 2^{2047} \leq \phi(n) \lt 2^{2048} $ 可爆破 $ k $(范围在$ \left\lceil\frac{2^{2063}}{2^{2048}}\right\rceil=\left\lceil2^{15}\right\rceil \lt k \lt \left\lceil\frac{2^{2064}}{2^{2047}}\right\rceil=\left\lceil2^{17}\right\rceil $)。
4.23.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes |
4.24 [AFCTF2018]可怜的RSA
4.24.1 题目
1 | # flag.enc |
4.24.2 解题思路
提取公钥 + 大素数分解 + 标准 RSA 解密
4.24.3 解题脚本
1 | import rsa |
4.25 [网鼎杯 2020 青龙组]you_raise_me_up
4.25.1 题目
1 | #!/usr/bin/env python |
4.25.2 解题思路
已知较小 $ m、n、c $ 求 $ e $
4.25.3 解题脚本
1 | from Crypto.Util.number import long_to_bytes |
4.26 RSA & what
4.26.1 题目
1 | # README.txt |
4.26.2 解题思路
共模攻击 + Base64 隐写
4.26.3 解题脚本
1 | import gmpy2 |
4.27 [NPUCTF2020]EzRSA
4.27.1 题目
1 | from gmpy2 import lcm , powmod , invert , gcd , mpz |
4.27.2 解题思路
$ \phi(n) $ 与 $ e $ 不互素
最大公约数和最小公倍数关系:$ \text{lcm}(a , b) \times \text{gcd}(a, b)=a \cdot b $,因为 $ n $ 长度为 2048 位,$ \phi(n) $ 长度 $ \leq n $,最小公倍数长度为 2045 位,所以最大公约数长度为 2-3 位,可爆破。
4.27.3 解题脚本
1 | from Crypto.Util.number import inverse, long_to_bytes, GCD |
4.28 [MRCTF2020]babyRSA
4.28.1 题目
1 | import sympy |
4.28.2 解题思路
计算多因数欧拉函数 + 标准 RSA 解密
4.28.3 解题脚本
1 | from math import prod |
4.29 [WUSTCTF2020]情书
4.29.1 题目
1 | Premise: Enumerate the alphabet by 0、1、2、..... 、25 |
4.29.2 解题思路
标准 RSA 解密 + 自定义码表替换
4.29.3 解题脚本
1 | if __name__ == "__main__": |
4.30 [WUSTCTF2020]dp_leaking_1s_very_d@angerous
4.30.1 题目
1 | e = 65537 |
4.30.2 解题思路
$ dp、dq $ 泄露
已知 $ dp、n、e、c $,求 $ m $
4.30.3 解题脚本
1 | from Crypto.Util.number import inverse, long_to_bytes |
4.31 [MRCTF2020]Easy_RSA
4.31.1 题目
1 | import sympy |
4.31.2 解题思路
求 $ P $:已知 $ n 、 \phi(n) $,求 $p、q$
求 $ Q $:已知 $e 、 d 、 n$,求 $p 、 q$
标准 RSA 解密
4.31.3 解题脚本
1 | import random |
4.32 [HDCTF2019]together
4.32.1 题目
1 | # pubkey1.pem |
4.32.2 解题思路
提取公钥 + 共模攻击
4.32.3 解题脚本
1 | import rsa |
4.33 [INSHack2017]rsa16m
4.33.1 题目
1 | # Challenge description: |
附件: rsa_16m.zip
4.33.2 解题思路
RSA 低公钥指数攻击
4.33.3 解题脚本
1 | import itertools |
4.34 坏蛋是雷宾
4.34.1 题目
1 | 老牌刺客之王混进了女王的住所。一天,女王得到了一个匿名举报,说她的侍卫里有一个刺客,叫做Rabin,而他的信息就在一份文件里,文件中有附带一个Pk,是523798549,密文是162853095,校验码二进制值是110001,根据说明是放在明文后一起加密的,明文与密文长度相同。加密算法和这位老牌刺客同名。快拯救女王,答案是求得的明文,进行32位md5小写哈希字符串,提交即可。 |
4.34.2 解题思路
RSA 低公钥指数攻击:特例 $ e=2 $ 的 Rabin 算法
奇偶校验
4.34.3 解题脚本
1 | import hashlib |
4.35 [INSHack2019]Yet Another RSA Challenge - Part 1
4.35.1 题目
1 | import subprocess |
4.35.2 解题思路
$ p $ 参数泄露(注意:有的 FC
不需要替换,需要爆破所有可能)
4.35.3 解题脚本
1 | from math import prod |
4.36 [RoarCTF2019]RSA
4.36.1 题目
1 | A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x |
4.36.2 解题思路
$ A $ 长度为 $ 2015 \lt 2019 $,所以 $ \left( (y \bmod x)^5 \bmod (x \bmod y) \right)^{2019} $ 值只能为 1 或 0,并且 $ \frac{y+1}{x} $ 结果要求为整数。$A$ 近似 $ y^{316} $,可解 $ x $ 和 $ y $。
p、q 参数设置不当(近似攻击)
4.36.3 解题脚本
1 | from Crypto.Util.number import inverse, long_to_bytes, isPrime |
5. 哈希与消息认证
5.1 MD5
5.1.1 题目
1 | e00cf25ad42683b3df678c61f42c6bda |
5.1.2 解题思路
MD5 在线查询
5.1.3 解题脚本
1 | https://www.cmd5.com/default.aspx |
5.2 丢失的MD5
5.2.1 题目
1 | import hashlib |
5.2.2 解题思路
MD5 爆破
针对特定 MD5 哈希值的爆破。遍历 ASCII 字符(32-126)寻找符合特定子串条件的 MD5 哈希值。
5.2.3 解题脚本
1 | import hashlib |
5.3 Windows系统密码
5.3.1 题目
1 | Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: |
5.3.2 解题思路
MD5 在线查询
5.3.3 解题脚本
1 | https://www.cmd5.com/default.aspx |
5.4 权限获得第一步
5.4.1 题目
1 | Administrator:500:806EDC27AA52E314AAD3B435B51404EE:F4AD50F57683D4260DFD48AA351A17A8::: |
5.4.2 解题思路
MD5 在线查询
5.4.3 解题脚本
1 | https://www.cmd5.com/default.aspx |
5.5 还原大师
5.5.1 题目
1 | 我们得到了一串神秘字符串:TASC?O3RJMV?WDJKX?ZM,问号部分是未知大写字母,为了确定这个神秘字符串,我们通过了其他途径获得了这个字串的32位MD5码。但是我们获得它的32位MD5码也是残缺不全,E903???4DAB????08?????51?80??8A?,请猜出神秘字符串的原本模样,并且提交这个字串的32位MD5码作为答案。 |
5.5.2 解题思路
MD5 爆破
针对特定 MD5 哈希值的爆破。遍历 ASCII 字符(32-126)寻找符合特定子串条件的 MD5 哈希值。
5.5.3 解题脚本
1 | import hashlib |
6. 应用密码学
7. 自定义构造题
7.1 Alice与Bob
7.1.1 题目
1 | 密码学历史中,有两位知名的杰出人物,Alice和Bob。他们的爱情经过置换和轮加密也难以混淆,即使是没有身份认证也可以知根知底。就像在数学王国中的素数一样,孤傲又热情。下面是一个大整数:98554799767,请分解为两个素数,分解后,小的放前面,大的放后面,合成一个新的数字,进行md5的32位小写哈希,提交答案。 |
7.1.2 解题思路
按照题目步骤写脚本。
7.1.3 解题脚本
1 | import requests |
7.2 达芬奇密码
7.2.1 题目
1 | 达芬奇一直是一个有争议的画家,科学家。。。小明为了研究他,从网上找到了名画蒙娜丽莎,一天深夜,小明突然从蒙娜丽莎背后的天空中看到了一串神秘的数字。顺带告诉小明达芬奇家窗台上有一串数字是关键。小明千里迢迢找到了这串数字,请将这个送分题做出来,亲,包邮哦(答案是一串32位十进制数字) |
7.2.2 解题思路
斐波拉契数列
数字列与数字串长度相同。依次取出数字列中的每个数字,查找其在斐波那契数列中的索引值,然后将密文中对应索引位置的字符移动到该索引指定的新位置,实现还原。
7.2.3 解题脚本
1 | from collections import deque |
7.3 [BJDCTF2020]easyrsa
7.3.1 题目
1 | from Crypto.Util.number import getPrime,bytes_to_long |
7.3.2 解题思路
三角函数
化简:$ \frac{1}{\frac{d}{dp} \arctan(p)} - \frac{1}{\frac{d}{dq} \operatorname{arth}(q)} $
对于 $\arctan(p)$,求导函数得:$\frac{d}{dp} \arctan(p)=\frac{1}{1+p^2}$;对于 $\operatorname{arth}(q)$(即 $\tanh^{-1}(q)$),求导函数得:$ \frac{d}{dp} \operatorname{arth}(q)=\frac{1}{1-q^2} $。可得:$ z=p^2+q^2 $。
已知 $p^2+q^2$ 和 $p \cdot q$ 可求 $ p 、 q $。
7.3.3 解题脚本
1 | import math |
7.4 [网鼎杯 2020 青龙组]boom
7.4.1 题目
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
7.4.2 解题思路
使用 IDA 反汇编 boom.exe,分析代码,flag 由三部分组成。
MD5 爆破 + 解三元一次方程组 + 解一元二次方程
7.4.3 解题脚本
1 | # https://www.cmd5.com/default.aspx |
7.5 [RoarCTF2019]babyRSA
7.5.1 题目
1 | import sympy |
7.5.2 解题思路
威尔逊定理:$ (A-1)! \equiv -1 \pmod A $
分析代码:$p = (B_1!) % A_1 \quad q = (B_2!)%A_2 \quad B_1 \lt A_1 \quad B_2 \lt A_2$
$$
\begin{gathered}
\because B! \cdot (B+1) \cdot (B+2) \cdot (B+3) \cdots (A-1)\ % \ A=−1\ \ %\ A
\
\therefore B!\ %\ A = [-(B+1) \cdot (B+2) \cdot (B+3) \cdots (A-1)]^{-1} \pmod A
\end{gathered}
$$
求出逆元可得 $ p、q 、r $。
7.5.3 解题脚本
1 | from base64 import b64decode |
7.6 [WUSTCTF2020]大数计算
7.6.1 题目
1 | flag等于 wctf2020{Part1-Part2-Part3-Part4} 每一Part都为数的十六进制形式(不需要0x),并用 '-' 连接 |

7.6.2 解题思路
按照要求写脚本。
7.6.3 解题脚本
1 | from sympy import symbols, integrate |
7.7 救世捷径
7.7.1 题目
1 | 一个名叫CPU的神秘大陆有26个国家,有些国家之间会有一条无向路,每条路径都有不同的长度和一段神秘代码,救世主尼奥要从国家1出发,赶往国家26拯救大陆,请你帮助救世主选择最短路径,而走过的路的神秘代码连接起来便是flag。 以下是数行数据,每行第一个,第二个数字代表这条路的两个端点国家,第三个数字代表路途长度,最后一个字符串便是神秘代码。路在附件中~ 帮助救世主尼奥吧,他快被吓尿了。。。 |
7.7.2 解题思路
最短路径问题:Dijkstra 算法
7.7.3 解题脚本
1 | import heapq |
8. 信息隐藏与隐写术
8.1 password
8.1.1 题目
1 | 姓名:张三 |
8.1.2 解题思路
key{} 中有 10 个数,猜测可能是“姓名缩写+生日”
8.1.3 解题脚本
1 | flag{zs19900315} |
8.2 [NPUCTF2020]这是什么觅🐎
8.2.1 题目

8.2.2 解题思路
文件改为压缩包格式解压,F1 W1 S22 S21 T12 S11 W1 S13
字母部分对应星期的英文首字母,T1
对应星期二、S1
对应星期六、S2
对应星期日;最后一个数字表示该星期下方的第几个具体日期。最终提取出一组数字 3, 1, 12, 5, 14, 4, 1, 18
,对应英文字母表序号还原出 flag。
8.2.3 解题脚本
1 | if __name__ == "__main__": |
8.3 [ACTF新生赛2020]crypto-classic0
8.3.1 题目
1 | # hint.txt |
8.3.2 解题思路
压缩包爆破,Archive 爆破 8 位数字(YYYYMMDD)获得压缩包密码 19990306
。获得 flag 加密算法文件:
1 | #include<stdio.h> |
简单逆向算法即可。
8.3.3 解题脚本
1 | def reverse(ciphertext): |
8.4 [ACTF新生赛2020]crypto-rsa0
8.4.1 题目
1 | 怎么办呢,出题人也太坏了,竟然把压缩包给伪加密了! |
8.4.2 解题思路
压缩包伪加密,压缩文件中的目录区标记 50 4B 01 02
,定位到目录文件头。后面的字段中,00 00
表示未启用加密(该字段为全局方式标志位,奇数表示加密,偶数表示未加密)。可使用 010 Editor 将第二个 50 4B 01 02
后的 09 00
修改为 00 00
,以解除加密标志。
解压得到加密脚本:
1 | from Cryptodome.Util.number import * |
标准 RSA 解密
8.4.3 解题脚本
1 | from math import prod |
[日常训练] Crypto Training - BUUCTF(一)