题目来源:buuCTF-crypto-RSA1
题目:
p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
很明显,给了密文c和一些参数,解密求m
一切以解题为目的的抄代码都是耍流氓,我们还是要从数学理论上去解决它,最后再根据数学理论来写代码。
公式推导:
先摆出已知条件:
c
≡
m
e
m
o
d
n
c≡m^{e} mod n
c≡memodn
m
≡
c
d
m
o
d
n
m≡c^{d} mod n
m≡cdmodn
ϕ
(
n
)
=
(
p
−
1
)
∗
(
q
−
1
)
ϕ(n)=(p−1)∗(q−1)
ϕ(n)=(p−1)∗(q−1)
d
∗
e
≡
1
m
o
d
ϕ
(
n
)
d∗e≡1 mod ϕ(n)
d∗e≡1modϕ(n)
d
p
≡
d
m
o
d
(
p
−
1
)
dp≡d mod (p−1)
dp≡dmod(p−1)
d
q
≡
d
m
o
d
(
q
−
1
)
dq≡d mod (q−1)
dq≡dmod(q−1)
目的很明确,要想得到m,就要得到 c d c^{d} cd
利用中国剩余定理,我们可以得到
m
1
≡
c
d
m
o
d
p
,
m
2
≡
c
d
m
o
d
q
m1≡c^{d} mod p,m2≡c^{d} mod q
m1≡cdmodp,m2≡cdmodq
这里肯定有很多人不理解,简单证明一下
由
m
≡
c
d
m
o
d
n
m≡c^{d} mod n
m≡cdmodn,可以得到式子
m
=
c
d
+
k
∗
n
m=c^{d}+k∗n
m=cd+k∗n
又因为
n
=
p
∗
q
n=p∗q
n=p∗q
所以可以得到
m
=
c
d
+
p
∗
q
∗
k
m=c^{d}+p∗q∗k
m=cd+p∗q∗k
上述式子,同时取余q和p,可以分别得到
m
1
≡
c
d
m
o
d
p
,
m
2
≡
c
d
m
o
d
q
m1≡c^{d} mod p,m2≡c^{d} mod q
m1≡cdmodp,m2≡cdmodq
带入上面的公式,可以得到 c d = k p + m 1 c^{d}=kp+m1 cd=kp+m1
我们把这个带入m2可以得到
m 2 ≡ ( k p + m 1 ) m o d q m2≡(kp+m1) mod q m2≡(kp+m1)modq
等式两边同时减去m1,可以得到
( m 2 − m 1 ) ≡ k p m o d q (m2−m1)≡kp mod q (m2−m1)≡kpmodq
这里因为 g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1
所以可以求p的逆元,得到
(
m
2
−
m
1
)
∗
p
−
1
≡
k
m
o
d
q
(m2−m1)∗p^{−1}≡k mod q
(m2−m1)∗p−1≡kmodq
所以这里得到如下式子
k
≡
(
m
2
−
m
1
)
∗
p
−
1
m
o
d
q
k≡(m2−m1)∗p^{−1} mod q
k≡(m2−m1)∗p−1modq
c
d
=
k
p
+
m
1
c^{d}=kp+m1
cd=kp+m1
我们上下两个式子合并,得到
c
d
=
(
(
m
2
−
m
1
)
∗
p
−
1
m
o
d
q
)
∗
p
+
m
1
c^{d}=((m2−m1)∗p^{−1} mod q)*p+m1
cd=((m2−m1)∗p−1modq)∗p+m1,
最后带入
m
≡
c
d
m
o
d
n
m≡c^{d} mod n
m≡cdmodn
得到
m
≡
(
(
(
m
2
−
m
1
)
∗
p
−
1
m
o
d
q
)
∗
p
+
m
1
)
m
o
d
n
m≡(((m2−m1)∗p^{−1} mod q)*p+m1) mod n
m≡(((m2−m1)∗p−1modq)∗p+m1)modn
现在只剩最后一步了,即这里的m1和m2怎么求?这时候我们有
d ≡ d p m o d ( p − 1 ) , d ≡ d q m o d ( q − 1 ) d≡d^{p} mod (p−1),d≡d^{q} mod (q−1) d≡dpmod(p−1),d≡dqmod(q−1)
分别带入m1,m2,有
m
1
≡
c
d
q
m
o
d
(
q
−
1
)
m
o
d
q
,
m1≡c^{dq mod (q−1)} mod q,
m1≡cdqmod(q−1)modq,
m
2
≡
c
d
p
m
o
d
(
p
−
1
)
m
o
d
p
m2≡c^{dp mod (p−1)} mod p
m2≡cdpmod(p−1)modp
这里肯定有人又不理解为什么可以直接带入了,我们再证明一下,这里用到了费马小定理即假如p是质数,且
g
c
d
(
k
,
p
)
=
1
gcd(k,p)=1
gcd(k,p)=1,则
k
(
p
−
1
)
≡
1
m
o
d
p
k(p−1)≡1 mod p
k(p−1)≡1modp
所以如果我们有等式
d=dp+k∗(p−1)
我们直接带入,有
m 2 ≡ c d p + k ∗ ( p − 1 ) m o d p m2≡c^{dp+k∗(p−1) }mod p m2≡cdp+k∗(p−1)modp
这里的指数,我们拆开,为
m 2 ≡ c d p ∗ c k ∗ ( p − 1 ) m o d p m2≡c^{dp}∗c^{k∗(p−1) }mod p m2≡cdp∗ck∗(p−1)modp
这里的
c
k
∗
(
p
−
1
)
≡
1
m
o
d
p
c^{k∗(p−1)}≡1 mod p
ck∗(p−1)≡1modp(用了刚才说的费马小定理)
所以
m2≡c^{dp} mod p$
那么m1根据对称性也可以同理得到
m 1 ≡ c d q m o d q m1≡c^{dq} mod q m1≡cdqmodq
最终,我们拥有了如下的条件:
m1≡c^{dq }mod q
m2≡c^{dp} mod p
m≡(((m2−m1)∗p−1 mod q)p+m1) mod n
一切就绪,等号右边的全部都是已知的,开算
上代码
import libnum
def egcd(a, b):
if (b == 0):
return 1, 0, a
else:
x, y, q = egcd(b, a % b) # q = GCD(a, b) = GCD(b, a%b)
x, y = y, (x - (a // b) * y)
return x, y, q
def mod_inv(a, b):
return egcd(a, b)[0] % b # 求a模b得逆
p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
invq=mod_inv(p,q)
mp=pow(c,dp,p)
mq=pow(c,dq,q)
m=((mp-mq)*invq%p)*q+mq
print(libnum.n2s(m))
最终得到答案