终于看懂了大佬的博客,结合自己的思考过程,写下这篇博客,做好记录,以便再次遇到
之前在buu上有刷到告诉dp和dq的,已经存了脚本
这次在ctfshow上刷到了funnyrsa3只告诉dp,网上有wp也写得清楚易懂,还有脚本,所以重要的是弄清原理
首先,
e = 65537
n = 13851998696110232034312408768370264747862778787235362033287301947690834384177869107768578977872169953363148442670412868565346964490724532894099772144625540138618913694240688555684873934424471837897053658485573395777349902581306875149677867098014969597240339327588421766510008083189109825385296069501377605893298996953970043168244444585264894721914216744153344106498382558756181912535774309211692338879110643793628550244212618635476290699881188640645260075209594318725693972840846967120418641315829098807385382509029722923894508557890331485536938749583463709142484622852210528766911899504093351926912519458381934550361
dp = 100611735902103791101540576986246738909129436434351921338402204616138072968334504710528544150282236463859239501881283845616704984276951309172293190252510177093383836388627040387414351112878231476909883325883401542820439430154583554163420769232994455628864269732485342860663552714235811175102557578574454173473
c = 6181444980714386809771037400474840421684417066099228619603249443862056564342775884427843519992558503521271217237572084931179577274213056759651748072521423406391343404390036640425926587772914253834826777952428924120724879097154106281898045222573790203042535146780386650453819006195025203611969467741808115336980555931965932953399428393416196507391201647015490298928857521725626891994892890499900822051002774649242597456942480104711177604984775375394980504583557491508969320498603227402590571065045541654263605281038512927133012338467311855856106905424708532806690350246294477230699496179884682385040569548652234893413
很简单只告诉了四个数字,RSA加密解密的式子就不再赘述
这里dp的意思就是
d p = d % ( p − 1 ) dp=d\ \%(p-1) dp=d %(p−1)
这是唯一的已知条件吧,所以就从这里开始推导
目标很明确,要么求p,要么求d,因为求出p一切就都出来了,所以我们试着能不能求出有关p的范围来尝试爆破
在这里提醒一点吧,一些做ctf密码学的萌新(比如我),总想着可以直接求出p的值来,但题目往往是让我们求得某个值的范围,然后用脚本爆破
∵ d p = d % ( p − 1 ) ∴ d = k 1 × ( p − 1 ) + d p 即 e × d = k 1 × e × ( p − 1 ) + d p × e 已 知 e × d ≡ 1 m o d ϕ ( n ) ∴ e × d = k 2 × ϕ ( n ) + 1 ∴ k 1 × e × ( p − 1 ) + d p × e = k 2 × ϕ ( n ) + 1 又 ∵ ϕ ( n ) = ( p − 1 ) × ( q − 1 ) , 带 入 得 k 1 × e × ( p − 1 ) + d p × e = k 2 × ( p − 1 ) × ( q − 1 ) + 1 整 理 得 d p × e = [ k 2 × ( q − 1 ) − k 1 × e ] ( p − 1 ) + 1 由 d p = d % ( p − 1 ) 易 知 d p > p − 1 ∴ e > [ k 1 × e + k 2 × ( q − 1 ) ] 设 X = [ k 1 × e + k 2 × ( q − 1 ) ] 已 知 e = 65537 , 只 需 要 枚 举 X 就 行 \because dp=d\ \%(p-1)\\ \therefore d=k1\times(p-1)+dp\\ 即e\times d=k1\times e\times (p-1)+dp\times e\\ 已知e\times d\equiv1\ mod\ \phi(n)\\ \therefore e\times d=k2\times \phi(n)+1\\ \therefore k1\times e\times (p-1)+dp\times e=k2\times \phi(n)+1\\ 又\because \phi(n)=(p-1)\times (q-1),带入得\\ k1\times e\times (p-1)+dp\times e=k2\times (p-1)\times (q-1)+1\\ 整理得dp\times e=[k2\times (q-1)-k1\times e](p-1)+1\\ 由dp=d\ \%(p-1)易知dp>p-1\\ \therefore e>[k1\times e+k2\times (q-1)]\\ 设X=[k1\times e+k2\times (q-1)]\\ 已知e=65537,只需要枚举X就行 ∵dp=d %(p−1)∴d=k1×(p−1)+dp即e×d=k1×e×(p−1)+dp×e已知e×d≡1 mod ϕ(n)∴e×d=k2×ϕ(n)+1∴k1×e×(p−1)+dp×e=k2×ϕ(n)+1又∵ϕ(n)=(p−1)×(q−1),带入得k1×e×(p−1)+dp×e=k2×(p−1)×(q−1)+1整理得dp×e=[k2×(q−1)−k1×e](p−1)+1由dp=d %(p−1)易知dp>p−1∴e>[k1×e+k2×(q−1)]设X=[k1×e+k2×(q−1)]已知e=65537,只需要枚举X就行
以上是完整的推导过程,这里讲解下思路
其实就是将 d p = d % ( p − 1 ) dp=d\ \%(p-1) dp=d %(p−1) 转化成一般代数的形式 d = k 1 × ( p − 1 ) + d p d=k1\times(p-1)+dp d=k1×(p−1)+dp
由于d和p是要求的未知量,所以我们就想去掉一个
结合已知的求逆元式子 e × d ≡ 1 m o d ϕ ( n ) e\times d\equiv1\ mod\ \phi(n) e×d≡1 mod ϕ(n) 换成的 e × d = k 2 × ϕ ( n ) + 1 ② e\times d=k2\times \phi(n)+1\quad② e×d=k2×ϕ(n)+1②
那我们把 ① × e ①\times e ①×e,得到和②左边一样的,右边等起来就是 k 1 × e × ( p − 1 ) + d p × e = k 2 × ϕ ( n ) + 1 k1\times e\times (p-1)+dp\times e=k2\times \phi(n)+1 k1×e×(p−1)+dp×e=k2×ϕ(n)+1 显然这里 ϕ n = ( p − 1 ) × ( q − 1 ) \phi n=(p-1)\times (q-1) ϕn=(p−1)×(q−1) 就不用说了
将这个式子整理得到
d p × e = [ k 2 × ( q − 1 ) − k 1 × e ] ( p − 1 ) + 1 ③ dp\times e=[k2\times (q-1)-k1\times e](p-1)+1 ③ dp×e=[k2×(q−1)−k1×e](p−1)+1③
(因为e和dp是已知的我们就放在一边,另外两项都有公因式(p-1)可以合并)
右边的+1暂且不看,因为无伤大雅
为什么说由题易知, d p > p − 1 dp>p-1 dp>p−1
因为最开始我们就知道 d p ≡ d m o d ( p − 1 ) dp\equiv d\ mod(p-1) dp≡d mod(p−1) 即 d = d p m o d ( p − 1 ) d=dp\ mod(p-1) d=dp mod(p−1)
如果 d p < p − 1 dp
那么d的值就是dp,我们可以去检验一下,发现出来的是乱码,所以显然 d p > p − 1 dp>p-1 dp>p−1
所以我们设 X = [ k 1 × e + k 2 × ( q − 1 ) ] , X < e X=[k1\times e+k2\times (q-1)],\quad X
剩下的我们只需要编写脚本,爆破 [ 1 , e ] [1,e] [1,e] 所有的情况,求出q,符合RSA基本要素之间的关系的就是我们要求的q
之后便是最基本的操作。
最后贴上自己的脚本,可能算不上很精炼,因为菜是一种原罪
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/2/3 13:59
# @Author : Will
# @File : funnyrsa3(script).py
# @Software: PyCharm
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert
def esayrsa(n, p, e, c):
q = n//p
phi = (p-1)*(q-1)
try:
d = invert(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
return flag
except:
return
e = 65537
n = 13851998696110232034312408768370264747862778787235362033287301947690834384177869107768578977872169953363148442670412868565346964490724532894099772144625540138618913694240688555684873934424471837897053658485573395777349902581306875149677867098014969597240339327588421766510008083189109825385296069501377605893298996953970043168244444585264894721914216744153344106498382558756181912535774309211692338879110643793628550244212618635476290699881188640645260075209594318725693972840846967120418641315829098807385382509029722923894508557890331485536938749583463709142484622852210528766911899504093351926912519458381934550361
dp = 100611735902103791101540576986246738909129436434351921338402204616138072968334504710528544150282236463859239501881283845616704984276951309172293190252510177093383836388627040387414351112878231476909883325883401542820439430154583554163420769232994455628864269732485342860663552714235811175102557578574454173473
c = 6181444980714386809771037400474840421684417066099228619603249443862056564342775884427843519992558503521271217237572084931179577274213056759651748072521423406391343404390036640425926587772914253834826777952428924120724879097154106281898045222573790203042535146780386650453819006195025203611969467741808115336980555931965932953399428393416196507391201647015490298928857521725626891994892890499900822051002774649242597456942480104711177604984775375394980504583557491508969320498603227402590571065045541654263605281038512927133012338467311855856106905424708532806690350246294477230699496179884682385040569548652234893413
for X in range(1, e+1):
# e * dp == (p-1) * X + 1
if 0 == (e*dp-1) % X:
p = (e*dp-1) // X + 1
if 0 == n % p:
flag = esayrsa(n, p, e, c)
print(flag)
break
总结,不太难的推导,对于刚入门的萌新(wo)来说也有一定的收获吧,希望对自己有用,大家有帮助XD
20210203