记录这次从9月初到10月末陆陆续续出的几道密码题
这是几次方? 疑惑!
描述
^ w ^
^ 小猫的眼睛在python里面到底是什么意思?不如先看看大蟒蛇 运算符号的优先级吧
题目
1 | from Crypto.Util.number import * |
- 出题思路
之前有遇到过运算符优先级的事,便拿来出题,异或运算符是先计算两边再进行异或的
解析
结合题目描述,在网上搜索并用 AI 解读描述
在 Python 中异或先计算两边,再进行异或操作
exp
1 | from Crypto.Util.number import * |
- flag
1 | flag{yihuo_yuan_lai_xian_ji_suan_liang_bian_de2333} |
欧拉欧拉!!
题目
1 | from Crypto.Util.number import * |
解析
p和q的生成方式独特,其中有
$q = x+i$
通过
1 | x = ((1 << bits) - 1) ^ p |
这行代码了解到,在二进制中p是和512个1异或得到x,
则
$p+x=2^{512} - 1$
(举例说明一下)不懂的同学可以了解一下二进制加法
1 | a = 1001 |
推导得到
$p+q=2^{512} - 1+i$
phi分解
$phi = (p-1)·(q-1)=n-(p+q)+1$
带入式子得
EXP
1 | # 创物者:善嵯峨 |
RSA?cmd5!
出题思路
rsa的签名,往往是给接收方B确定发送方A的身份用的,但如果发送方用不安全的哈希算法来计算信息的信息摘要,那么有可能被中途的窃密者C利用而得到明文
题目
1 | from Crypto.Util.number import * |
解析
这里我们得到了通过c,s,n,e,和平时的rsa不同,这里多了s,让我们看看这个s是什么
1 | def get_MD5(m0): |
计算了m0的md5 hm0
,然后将hm0转成整数hm1进行计算
那么我们有e,理解rsa解密原理
那么再结合题目名字和描述,去cmd5.com找hm1的结果
m为adm0n12
flag为
1 | flag = 'flag{th1s_1s_my_k3y:' + m + '0x' + hashlib.sha256(m.encode()).hexdigest() + '}' |
flag{th1s_1s_my_k3y:adm0n120xbfab06114aa460b85135659e359fe443f9d91950ca95cbb2cbd6f88453e2b08b}
exp
1 | from Crypto.Util.number import * |
格格你好棒
题目
1 | from Crypto.Util.number import * |
格密码基础
格定义
https://blog.csdn.net/jayq1/article/details/140872034
矩阵乘法
https://zhuanlan.zhihu.com/p/158776486
NTRU密码
参数
模:$p$
私钥:$(f,g)$
公钥:
临时密钥$r$
加密:
解密:
再乘上$f^{−1}$即可得到$m$。
参数大小:
显然当时才能正确解密。
考虑格
同时我们有$h·f + k·p=g$,
此时我们发现 $(f,g)$便是格中的一个格点。
因为$(f,k)L=(f,f·h+p·k)=(f,g)$
则如果我们能够找到$(f,k)$ 则可以得到$(f,g)$
更多条件
此时发现向量$\vec{b}=(f,g)$的长度为
@分析——为什么构造这样的格
目标为$\vec{v}=(f,g)$ 私钥
已知式子
下划线的 h和p是已知量
观察式子,左边的g是我们想要求得,右边中也有f是我们想要的,而k并不重要。
则结合向量和格
我们构造的格最后一列为 h,p或者p,h
$\vec{(f,k)}\begin{bmatrix} &&h\\&&p\end{bmatrix}$或者$\vec{(k,f)} \begin{bmatrix} &&p\\&&h\end{bmatrix}$
为了获得f,格的第一列第一个为1,然后补0 (或者相反)
$\vec{(f,k)}\begin{bmatrix} 1&h\\0&p\end{bmatrix}$或者$\vec{(k,f)} \begin{bmatrix} 0&p\\1&h\end{bmatrix}$
矩阵相乘得到结果$\vec{(f,g)}$
通过LLL算法得到最短向量$\vec{v}$
然后取值$f = \vec{v}[0] \\g=\vec{v}[1]$
又有式子
两边同时乘f,得
转换一下
但r未知,此路不通,回上一个式子1
在模p的同时再模上g去消r
即
明确目标:
找到私钥(f,g)
构造格:
由公钥公式得到g = hf + kp 因为右边只有两项,确定n维数为2,且只有h和p已知,得知最后我们要构造的格的最后一列是h,p,再推出L前面相乘的向量是(f,k),最后再补上前一列1,0。
解密
用LLL算法得到最短向量v后,对照当初设想的v= (f,g),令f = v[0],g = v[1],
获得f,g后,带入解密式子,因为r是临时密钥,无从得知,所以我们先模上p,再模上g,消去r。最后再乘上f关于模g的逆元,求得m。
解析
从题目和描述,知识点指向 格密码
题目给了一个断言
1 | ((p+2*r) * 3*a + q) % b < 70`,可以看成`h = ((p-2·r) · 3·a + q) mod b < 70 |
其中r和h都是有范围的,最大的范围r 也是2^14 - 2^15之间,对于计算机而言相当小,可以爆破,所以当成已知数
化简式子,把模消去
(p-2·r) · 3·a +k·b = h - q
和NTRU的式子相似 (NTRU: c = (r*h + m) % p
)
·构造
1 | L = [[1, 3·a], |
发现
$(p-r,k)L = (p-2·r, -q+h)=\vec{v}$
且
exp
1 | #sagemath |
建议升级一下sagemath版本,参照这位师傅的文章Arch下的Sage安装 - Shin’s Blog (shinichicun.top)
碎碎念
一开始听群里面说想学格密码,于是在week5打算出一个
在笔记中寻找许久,便把窃取目标盯上了xenny师傅的格密码课程的P3
直接抄违背了出题初心,但是P3的解题内核始终吸引着我,自己动手推导式子构造格,(在这对因为我窃取题目的行为而受伤的师傅们说声对不起!)
那么我就转向修改参数,以往的rsa题目,在我手动调试验证各个参数大小关系的时候,都是能满足自身的关系的。
但在这题 assert ((p-r) * a + q) % b < 50 似乎发生了变化,随意getPrime()的参数根本满足不了前面这个式子,换句话来说,这个式子太过于严谨了,怎么能取到那么合适的值,把h从1536位降到5位
答案是getPrime + 自己构造
让我们看原题目是怎么写的
1 | a = getPrime(1024) |
关键步((p-r) a + q) % b < 50,那么我们只用**先getPrime()生成p,q,r,a,然后手动取一个(或者取随机数)h 就行,让b = ((p-r) a + q) - h 就行**
等想到这步时,我才发现((p-r) a + q)的位数和b相近(前者最大项是p·a),这才能使得 h = ((p-r) a + q) - b 成立,而不是 h = ((p-r) · a + q) - K·b
代码附上
1 | a = getPrime(1024) |
调试的方法
可以改a,p,q的位数,r的范围需要后面在解题代码中看看跑的速度来调整,注意:b的位数要大于2倍的p的位数(推导见Hermite定理)
式子也能改,式子的灵魂就是最大项p·a与b在位数上相近,需要自己爆破的数字很小且可控,式子的未知数个数是5个,只有2个知道范围,k和p,q都不知,式子 导向 用格级规约LLL来解决
式子各项的系数,r的可以随意改,只要不接近p//r,exp只需要改动pp = p - t*r 中的t;
a的系数改动就要改格中a的系数
q的系数改动还不太清楚,改完exp就跑不动,也许是向量内不平衡
h改动涉及爆破范围的扩大与缩小,只需要对应的改动exp的h
1 | for h in range(50): |
完整出题代码如下
1 | from Crypto.Util.number import * |
先将if 0 :改为1,执行临近代码块,获取[p,q] [a,r] [b,h] 然后直接复制到下方,将if 1:改成0,获取c,a,b
提取r,复制
放到解题脚本调试
1 | #sagemath |
先用r 替换
1 | for r in tqdm(range(2**8,2**9)): |
中的2**8,跳过遍历环节,看看能否得到结果
如果可以
那么再换回成2**8
看看遍历速度和所需时间,这里需要2分钟,实际上解题只需要22秒
两个sagemath版本(Windows的9.3和Linux的10.x)都要测试速度 , 以免新生因为环境问题而困扰
更换了参数和式子,也算半个魔改了(