前言
这里记录了一些平常做题或者打比赛时遇到的有趣的不会做的Crypto题目,*表示赛时没有做出来,赛后复现的题目;持续更新(大概)。
Bytectf 2024
一道可能有思路但有思路不太可能的lfsr和一道0解的抽象dlp题目构成了我这个抽象的周末(悲)。
*magic_lfsr
题目
1 | from Crypto.Cipher import AES |
赛时想到了打ff的真值表去简化这个不可逆的函数,但是并没有想出如何去构造新函数;赛后参考W&M的wp复现才发现对LFSR的理解还是太浅了。
EXP
首先打ff的真值表
1 | from Crypto.Util.number import * |
这里构造了一个新函数:(x0+x1+x3)%2,打表发现只有1种情况不符合,考虑爆破最后一种情况构造m,使得
根据out中1位填充m的前n(n=127)列,并爆破最后两列所有可能的0位,解AES获得flag 完整exp:
1 | from Crypto.Cipher import AES |
*decipher Diffie-Hellman
题目
1 | import random |
hint: 有限空间爆破
根据lcg生成的两个相邻值可以解出p,然后开始挂机
SCTF 2024
学长们尽力了,密码手在干什么?()
Signin
题目
1 | from sage.all import * |
exp
注意到d的位数在128bit到256bit之间,且满足:
k与d数量级接近 对上式进行变换,可以构造copper如下:
mod e下有如下的多项式:
copper解出k与p+q的值即可。 代码如下:
1 | from Crypto.Util.number import * |
不完全阻塞干扰
题目
题目给出了部分私钥,手撕发现有p和q的高位
1 | n = 0x67f0aa4e974a63a1ffe8d5c23e5d3c431653ae41cc746f305f62a9f193f22486cb7ef1b275634818f46d0752a5139e19918271fa0d7d27bc660d2b72414d08ea52c8837f949c7baecc3029ba31727ef3bf120d9926c02d7412f187e98dc56dd07b987d2cc191ad56164a144f28b2f70a15d105588a4f27fbb2891fc527bd6890a5f795b5c48476a6bf9dfb67b7e1ebc7b1b086cd28b58c68955bfdf44ecce11ffacdf654551b159b7832040cc28ee8ebea48f8672d53e3de88fcfbb5fb276b503880dd34d5993335ddf8ccb96c1b4d79f502d72104765ad9c2b1858a17af3d5be44fa3cbf4b8eeb942aa3942a3871d2c65ac70289123fc2e9f9b25cbfcbd7841096060fa504c3a07b591493c64c88d0bb45285a85b5f7d59db98faa00c2cd3fbb63da599205f1cab0df52cf7b431a0ee4a7e35696546ce9d03ef595ecee92d2142c92e97d2744939703455b4c70dec27c321ec6b83c029622e83a9e0d55d0b258d95d4e61291865dda76dc619fce9577990429c6e77e9d40781e3b2f449701b83e8b0c6c66eb380f96473e5d422efee8b2b0e88b716b00a79c9d514ca3ad9d2dee526609ff9541732a4198d11b9dbfbb2e55c24d80ea522d0786e3355f23606a5d38a72de4eefc8b6bfc482248a2862cb69d8e0e3d316597da9d80828be85054faf15fc369caacafb815c6973c171940683d56a1a1967b09b7ffa3fbe5b2e08699759d84d71603f516447696bb27322a69f39f6ca253e00dc9555d5f97328070c467f3663cc489aad130f28c42f35bf88c571920ab92acb8f75d03e35a75103c5bd96f061c96bd02af6e1d191b0dd164bc721377003edbf5d3ef65a5e9046385356b521623bee37f164850a0a7afb0ed4e7e8bd9afe1298f7d532bc9ad941812d332aece75d1cccb1ff69fd42b31f248ae579d9e0d6a14b0546e784ba940e32bd01c395df8ff4584040462b5479fa07336d503dc332e70fc06d9463297fc042b623d56f87efaa525a9b580e314d90d1211893ed407a26508deaa0a13c9ee8c902b9e1c3a02fe9a51452c02ee7bdcc85c0eff63891e24703bd265d9c9dbf456e2af9409538bce0fecc7ebab20266aaab06c766c3ea6cda9cb9ba5e1d024b7dc3d73e76f6a333197bad87c4fb34d565a0014aac72825e41adcfeadadc87acef40ad84b7c55691abad561be0550ea0a988470c427432acb8feb2b9d2d2598fb2089bb91bbd9cb199e892d36164d8bf3ecd54576a97134047a12da84207485bb4e5 |
后根据pkl文件可以发现公钥生成方法和密文
1 | # The ship crashed into the sun, causing a massive magnetic storm |
很显然可以直接构造二元copper去解(然后我被参数卡了一天 令人感叹)
1 | import pickle |
感觉是我对二元copper的参数理解有问题(
*whisper
题目
题目给出了两个公钥pem和一个密文,根据pem可以得到:
1 | n1 = 0x1b5d4fe0aa6782e275d4ce12a6d57562efbbe7db6f5277255b891729bfa2a18d3edb49843d7989a37b9516be2df8ca939058e65f64b5fb2071bea4f5f8d1392895b32bf0377d99f4f79979125e5db01cdb5080a1c2d665c9ac31b5823025499c9513277bae5e7a846cd271c4396e2ba219020e58a9055cb18a28d36a00bf717b |
一开始的思路
一开始完全不知道这是什么,去网上查了解了Dual RSA的密钥体制,意识到这题应该是通过d过小攻击,先想到如下构造:
理论上对A配平后规约可以得到,然而改了半天跑不出来
exp
看wp发现有专用于攻击dual RSA的脚本,并且意识到爆破几位好像是可以用上面的格规出来的(大概)
1 | from sage.all import * |
*LinearARTs
题目
1 | from random import choices |
看着一堆东西,但是给了一堆信息,最后居然只需要造格子打lwe就行 早知道当时就应该先做这个()
exp
代码修改自鸡块大佬的脚本
1 | from Crypto.Util.number import * |
moectf 2024
被新生赛薄纱()
rsa_revenge
题目
1 | from Crypto.Util.number import getPrime, isPrime, bytes_to_long |
二进制下的反素数,逐位爆破,注意判断p*q高位是否与n一致即可
*hidden_poly
题目
1 | from Crypto.Util.Padding import pad |
我的思路
已知如下等式:
直接构造格子有:
但是根本没法配平,卡住了()
EXP
对等式转化一下得到:
可以构造格子:
可以直接得到系数 代码如下
1 | from Crypto.Util.Padding import pad |
*ezLCG
题目
1 | from sage.all import * |
exp
DSA签名,且nonce为LCG生成;注意到LCG的模数和DSA使用的一致,考虑去造同余方程组去解但是我完全不会Groebner
代码如下:
1 | from hashlib import sha1 |
基本是照着板子抄的,后面该认真学一下groebner了()
DASCTF 十月
太会套了crypto()
ez_RSA
题目
1 | from Crypto.Util.number import * |
exp
part 1
已知在上的等式:
连分数展开得到num1和num2
part 2
生成两个512素数乘积得到n2,并给出以下等式:
因为num1和num2已知,且e1, e2并不大,因此直接做多项式GCD就可以得到p,至此就可以解RSA获得flag
part 3
已知:
在模q下显然有:
所以有:
代码如下:
1 | from Crypto.Util.number import * |
*easy_xor
题目
1 | import os |
exp
part 1
最后的b = A*x + e显然是一个LWE样本,解LWE可以得到向量x,也就得到了q,从而得到矩阵Q
part 2
根据代码有如下等式:
而第二个式子在矩阵意义下等价于:
因此有:
解矩阵方程得到P,从而得到p
*part 3
铸币了,打的时候没想到咋做
最后一步的key进行了如下操作:
该式可以转化为:
展开多项式得到:
系数都很小,造格子LLL即可获得系数,然后从后往前两两做差并异或,就能恢复key
代码如下:
1 | from sage.all import * |