给校内纳新赛出的五道题,涉及编码解码、LCG入门、古典密码入门、RSA和sagemath软件安装。都能被AI一把梭的难度,也是骗点新生来学密码(bushi)
纳新赛密码wp
编码code
简单
描述
1 | 计算机是如何传递信息的? |
题目(带注释版)
1 | # How to use mathematics to represent information? # 题目借鉴来源0XGame南京邮电2024 |
解析
- 第一个块
m0
直接写入m0.txt中,考察ctfer读取文件的能力,为后面题目做准备。 - 第二个块
m1
被转换为长整数,这是将信息转换为数学表示的一种方式。 - 第三个块
m2
被转换为十六进制字符串,然后再次转换为字节数组,这是另一种数学表示形式。 - 第四个块
m3
被转换为base64编码的字节数组,这是将信息转换为数学表示的另一种方式。
EXP
1 | from base64 import b64decode |
FLAG
1 | SeeUSec{WOWWOW_U_really_learn_how_to_decode_these_code!!!!!} |
古典入门
中等
描述
1 | 古典密码大扫盲 |
题目(带注释版)
1 | # 打开文件flag.txt并读取内容到变量FLAG |
解析
古典密码按照加密方法分为替换
和移位
本题中
flag1$\to$c1:替换
,异或
flag2$\to$c2:移位
,栅栏密码
task.py流程
- 读取flag.txt:脚本首先打开并读取一个名为
flag.txt
的文件,该文件包含完整的flag。 - 分割flag:flag被分成两部分,
flag1
是前32个字符,flag2
是剩余的字符。 - 加密flag1:
- 使用异或操作对
flag1
进行加密,密钥是k1
。 k1
是一个可重复的字符串,用于确保可以与flag1
中的每个字符进行异或操作。- 加密后的结果存储在变量
c1
中。
- 使用异或操作对
- 加密flag2:
- 使用栅栏密码对
flag2
进行加密,密钥是k2
,这里k2
是栅栏密码的行数。 - 栅栏密码的工作原理是将字符按行排列,然后按列读取来构造密文。
- 加密后的结果存储在列表
c2
中。
- 使用栅栏密码对
- 写入加密后的flag:
- 将加密后的
flag1
(即c1
)写入文件c1.txt
。 - 将加密后的
flag2
(即c2
)转换为字符串并写入文件c2.txt
。
- 将加密后的
在CTF比赛中,这种类型的题目通常要求参与者解密这个过程,即解密c1.txt
和c2.txt
来获取原始的flag。上述代码提供了加密的过程,而参与者需要编写解密脚本来恢复原始的flag。
知识点
异或操作(XOR)
异或(exclusive OR,通常表示为 XOR)是一种在数字逻辑中使用的二进制操作,它产生一个真值(true value)当且仅当两个输入不相同时。在Python中,异或操作用 ^
表示。
特点:
- 如果两个比较的位相同,结果是0;如果不同,结果是1。
- 异或操作是可交换的,即
a ^ b
和b ^ a
的结果是相同的。 - 异或操作是可结合的,即
(a ^ b) ^ c
和a ^ (b ^ c)
的结果是相同的。 - 任何数与0进行异或操作,结果都是其本身,即
a ^ 0 = a
。 - 任何数与其自身进行异或操作,结果是0,即
a ^ a = 0
。
加密和解密:
在加密中,异或操作通常用于简单的加密算法,因为它的可逆性。以下是如何使用异或进行加密和解密的示例:
1 | # 加密 |
在这个例子中,plaintext
是要加密的文本,key
是密钥。加密和解密过程完全相同,因为异或操作的可逆性。这意味着你可以用相同的密钥对密文进行相同的操作来获取原始文本。
栅栏密码
栅栏密码是一种简单的转换密码,它将消息的字母分成几行(行数由密钥决定),然后按行读取来构造密文。
加密过程:
- 确定栅栏的“行数”(即密钥)。
- 将明文消息分成几行,每行的字符数相同或尽可能接近。
- 从第一行开始,按顺序读取每个字符,然后继续到下一行,直到消息的末尾。
解密过程:
- 确定栅栏的“行数”(即密钥)。
- 计算密文消息的总长度,并确定每行的字符数。
- 创建一个与密文长度相同的字符串数组。
- 按照加密时的相反顺序,将密文字符填充到数组中。
- 将数组转换回字符串,得到原始明文。
示例:
假设我们有明文 “HELLO WORLD” 和密钥 3(即分成3行)。
加密过程:
1 | H . . O . . W . . . |
按行读取得到密文:“HOL ELORLWD”.
解密过程:
- 确定密钥为3,密文长度为11。
- 计算每行的字符数,大约为4(11/3向上取整)。
- 创建一个长度为11的字符串数组。
- 按照加密时的相反顺序填充数组:
1 | HOL ELORLWD |
填充结果:
1 | H . . O . . W . . . |
5.将数组转换回字符串得到 “HELLO WORLD”。
本题为ctf初学者提供了异或操作和栅栏密码
背后的置换和移位这两大古典密码核心的基本理解。
EXP
1 | # 打开文件c1.txt并读取内容到变量c1 |
FLAG
1 | SeeUSec{this_is_b@by_replacement_@nd_th1s_is_baby_shift!!0*0} |
baby_LCG
中等
1 | 这个LCG就是逊辣 |
题目(带注释版)
1 | from Crypto.Util.number import * # 导入Crypto库中的number模块,用于处理数字相关操作 |
解析
挑战目标:
- 目标:理解线性同余发生器(LCG)的工作原理,并利用泄露的信息解密密文。
挑战1:基础LCG生成
- 解析:
- LCG类用于生成一个512位的线性同余发生器。
- 初始化方法接收一个参数seed,用于指定初始状态。
next
方法生成下一个随机数。show
方法显示当前状态。- 在这个挑战中,我们使用flag的长度作为种子创建了LCG实例。
挑战2:泄露的LCG状态
- 目标:理解如何利用泄露的LCG状态解密密文。
- 解析:
- LCG实例泄露了三个状态值:a, b, N。
- 这些状态值是生成随机数的关键信息。
- 利用泄露的a, b, N,我们可以重新创建LCG实例,并使用它来生成密文。
- 解密步骤:
- 从泄露中获取a, b, N。
- 使用这些值创建LCG实例。
- 使用LCG实例生成密文。
这里需要注意一点
在带模运算中,没有除法,只有逆元
$\frac {a}{b} \equiv a\cdot b^{-1} \pmod c$
python中Crypto.Util.number
提供了inverse(b,c)
函数计算b在模c下的逆元
EXP
1 | from Crypto.Util.number import * |
FLAG
1 | SeeUSec{WoW_LCG_is_funny} |
RSA_baby_to_EZ
困难
描述
1 | RSA大锅炖,一共三道“主食” |
题目(带注释版)
1 | # 一共有三个挑战,由简单到中等,现在开始你的Rsa学习之旅吧 |
解析
挑战1:基础RSA加密
- 目标:理解RSA加密的基础流程,并利用泄露的信息解密密文。
- 解析:
- RSA类生成了一个512位的RSA密钥对,包括公钥(e, n)和私钥(d)。
leak1
方法泄露了私钥中的一个素数p,这是解密的关键信息。- 加密函数
enRSA
使用公钥加密了flag的前22个字符。 - 解密步骤:
- 从
leak1
获取p。 - 使用公钥(e, n)和泄露的p,可以计算q(因为n = p * q)。
- 计算phi(n) = (p-1) * (q-1)。
- 计算私钥d,它是e模phi(n)的逆元。
- 使用私钥d解密密文c1。
- 从
挑战2:利用已知私钥分量解密
- 目标:理解如何使用RSA的私钥分量解密密文。
- 解析:
- 与挑战1类似,RSA类生成了一个512位的RSA密钥对。
leak2
方法泄露了私钥中的两个素数p和q,以及两个私钥分量dp
和dq
。- 加密函数
enRSA
使用公钥加密了flag的第22到第51个字符。 - 解密步骤:
- 从
leak2
获取$p, q, dp, dq$。 - 使用
dp
和dq
可以解密密文c2,因为RSA加密的密文可以通过分别计算(c^dp mod p)和(c^dq mod q)来解密。 - 使用中国剩余定理(CRT)合并这两个解密结果,得到原始明文。
- 从
挑战3:RSA私钥文件泄露
- 目标:理解如何使用RSA私钥文件解密密文。
- 解析:
- RSA类生成了一个512位的RSA密钥对。
- 加密函数
enRSA
使用公钥加密了flag的第51个字符之后的所有字符。 - 私钥被导出为PEM格式的文件
privatekey.pem
。 - 解密步骤:
- 读取
privatekey.pem
文件获取私钥。 - 使用私钥解密文件
c3.txt
中的密文c3。
- 读取
EXP
1 | from Crypto.Util.number import * |
FLAG
1 | SeeUSec{Start_to_solve_WoW_u_really_know_dp&dq_leak_&&_U_2_m@ster_0f_RSA!!!!!!!} |
你有装sagemath软件并配置好了吗?
中等
描述
1 | 贤者拿到了一个EXP,按道理来说用python运行一下就能出flag了,但她不认识这个EXP的后缀名 |
题目(带注释版)
1 | from Crypto.Util.number import * |
解析
按照题目描述安装软件并配置
网上能搜到相关sagemath软件安装的详细教程
然后还需要我们自己给sagemath装个pycryptodome库
FLAG
1 | SeeUSec{SageMath_is_very_helpful_for_learning_about_cryptography} |