moectfwp
Crypto
跟风一下:入门指北写得很好推荐看
moeSign1n
阅读代码,题目逻辑其实很简单:
设m = b'MoeCTF 2026'吧
菜单1:加密除了m的任意内容并返回密文
菜单2:提交一个密文,解密后是m给你flag
所以题目就是要在不直接加密m的原文的情况下加密m
这里利用rsa的乘法同态性就能做到
我们把m 拆成m1*m2,分别加密m1,m2,再$E(m_1) \cdot E(m_2) $
就在不直接加密m的情况下得到m的密文
1 | |
wsl_Sign1n
sage是个好东西,大家可以多多研究一下,密码手必备神器
justXOR
读题发现是xor加密,题目给了密钥key的生成逻辑,我们尝试还原key就能解密
key生成逻辑
因为初始状态和生成方法都已知,所有看完代码的第一反应就是再把gen_key()函数再跑一次就能拿到key
但是马上就会发现问题:n数字过大,跑完n轮循环几乎不可能,所以另寻他法求解key
我们仔细分析代码:发现这个生成key的式子就是一个数列的递推式,我们求出这个数列的通项公式就能不要跑完range(n-1)就能拿到key
1 | |
ez_f3mr4t
这个题出发点肯定在q = next_prime(p ^ ((1<<512)-1))
设 m = 1<<512,t = p^m 不难发现t其实就是p的按位取反,进一步我们可以发现:p + t = M
由此我们可以分析出p,q大致范围
题目中:
q=next_prime(M−p)q
所以存在一个很小的 gap,使得:
q=M−p+gapq
于是:
p+q=M+gap
令:
S=M+gap
那么 p,q 是方程:
x2−Sx+n=0
的两个根,判别式为:
Δ=S2−4n
当 gap 正确时,\Delta 是完全平方数。
枚举很小的奇数 gap 即可分解 n,然后解 RSA。
1 | |
ez_fermat
给了一个hint,从hint入手
因为 a*p + b ≡ b (mod p),所以:
plain
1 | |
第二步:关键变形 —— 把未知的 q 换成已知的 n
由费马小定理,模 p 时指数可以对 p-1 取模。注意 n = pq,而 p ≡ 1 (mod p-1),所以:
1 | |
于是:
1 | |
也就是说 p 整除 (b^n − hint),而 b、n、hint 全是已知量
第三步:gcd 出 p,由此分解n
1 | |
from Crypto.Util.number import *
from gmpy2 import *
n = 15962603324053600624662899467930954606237037554051572101066176482327650464579501876010780067612122315010349894395035821617153081982429716234378979239633769779503395609504372912298014522344609346937078959678893005192469085672940628091531228571447786013091492389216237976408692434723698967667324605921896928717731731591488800520224411239128106892402734198486634978989319563704879076976307439748456769245703782902660583833942684475506024284563786886608632662629581206716450648212025254862836883526055933841863348546872473877054469843468332542834452213365868510001991952142536759384940216228753729399187149594010090304067
c = 4281919068424886012214413435957379635517466043647380176350221253614623990599452495938689758001256045320061491376355750164051326734927905972267385611552894838140009898450267453653097466286838460889968896032216593811984942511165228143089457988630435810304672454147149556110542203084341901598519587611096893432307236558970264536719689039318023572680185246871600989317992399536729717958072642243834689061928667913495884682029212015071613730401843271641197254089900489231738518876415262001687002012972665662364940457678043829768126263211295258465202419686281997749861180041439407866197636369525192971926660559217573713931
hint = 8894364790280693556124457666776501614023509475927164016497858629229215409128965020674642063592770935057209719989294548263833927477972267267951214184209046168773196349537926982123382473522039515862138755400978350128128233701795758152143272668945626119949376162344749760499165210224412751964322150037199401111258869439672762883792051818112500032192131948644557686621759867629440824691768395882797936616839572906841251000681054283164497419314938363871139253289134458466501698235039234455154975165111296198209091586550990873209534256929400689017034618807232508747449076486852786199340704419120538526208691066898035362296
a, b = 0x2025, 0x2026
e = 65537
p = gcd(pow(b,n,n) - hint,n)
q = n // p
phi = (p-1)*(q-1)
d = inverse(e,phi)
print(long_to_bytes(pow(c,d,n)))
```s
