RSA-详解dp泄漏

it2025-02-16  25

原理:

0.基本数学公式

a = k b + p a = kb + p a=kb+p

a m o d b = p a mod b =p amodb=p

1.RSA的基本公式

c ≡ m e m o d n c \equiv m^emodn cmemodn m ≡ c d m o d n m\equiv c^dmodn mcdmodn ϕ ( n ) = ( p − 1 ) × ( q − 1 ) \phi(n)=(p-1)\times(q-1) ϕ(n)=(p1)×(q1) d × e ≡ 1 m o d ϕ ( n ) d\times e \equiv1mod\phi (n) d×e1modϕ(n)

2.dp是什么

d p ≡ d m o d ( p − 1 ) dp\equiv d mod(p-1) dpdmod(p1)

3.推导过程

将该公式变形:

d p ≡ d m o d ( p − 1 ) dp\equiv d mod(p-1) dpdmod(p1) ⇒ \Rightarrow d p × e dp \times e dp×e ≡ \equiv d × e m o d ( p − 1 ) d \times e mod (p-1) d×emod(p1) ⇒ \Rightarrow d × e ≡ k × ( p − 1 ) + d p × e d \times e \equiv k \times (p-1) + dp \times e d×ek×(p1)+dp×e

变形后的公式与下式结合

d × e ≡ 1 m o d ϕ ( n ) d\times e \equiv1mod\phi (n) d×e1modϕ(n)

因为:

ϕ ( n ) = ( p − 1 ) × ( q − 1 ) \phi(n)=(p-1)\times(q-1) ϕ(n)=(p1)×(q1)

所以我们可以进行变形:

⇒ \Rightarrow d × e ≡ 1 m o d ( p − 1 ) × ( q − 1 ) d\times e \equiv1mod(p-1) \times (q-1) d×e1mod(p1)×(q1)

得到:

k × ( p − 1 ) + d p × e = 1 m o d ϕ ( n ) k \times (p-1) + dp \times e=1mod\phi (n) k×(p1)+dp×e=1modϕ(n)

再次变形:

k 1 × ( p − 1 ) + d p × e = 1 m o d ( p − 1 ) × ( q − 1 ) k_1 \times (p-1) + dp \times e =1mod (p-1)\times(q-1) k1×(p1)+dp×e=1mod(p1)×(q1)

结合:

k 1 × ( p − 1 ) + d p × e = k 2 × ( p − 1 ) × ( q − 1 ) + 1 k_1 \times (p-1) + dp \times e = k_2 \times (p-1) \times (q-1) +1 k1×(p1)+dp×e=k2×(p1)×(q1)+1

⇒ \Rightarrow d p × e dp \times e dp×e= [ k 2 × ( p − 1 ) × ( q − 1 ) + 1 ] − [ k 1 × ( p − 1 ) ] [k_2 \times (p-1) \times (q-1) +1] - [k_1 \times (p-1)] [k2×(p1)×(q1)+1][k1×(p1)]

⇒ \Rightarrow d p × e dp \times e dp×e= [ k 2 × ( q − 1 ) − k 1 ] × ( p − 1 ) + 1 [k_2 \times (q-1) - k_1] \times (p-1) +1 [k2×(q1)k1]×(p1)+1

设 : X = k 2 × ( q − 1 ) − k 1 设:X = k_2 \times (q-1) - k_1 X=k2×(q1)k1

⇒ \Rightarrow d p × e = dp \times e= dp×e= X × ( p − 1 ) + 1 X \times (p-1) +1 X×(p1)+1

⇒ \Rightarrow d p < p − 1 dp < p-1 dp<p1 ⇒ \Rightarrow X < e X < e X<e ⇒ \Rightarrow X ∈ ( 0 , e ) X \in (0,e) X(0,e)

4.求p

遍历 X X X(65537种可能),求出 ( p − 1 ) (p-1) (p1),得到 p p p且能被 n n n整除;接下来就是常规RSA的解法

for i in range(1,65538): if (dp*e-1)%i == 0: if n%(((dp*e-1)/i)+1)==0: p=((dp*e-1)/i)+1 q=n/(((dp*e-1)/i)+1) phi = (p-1)*(q-1) d = gmpy2.invert(e,phi)%phi

例题:

[WUSTCTF2020]dp_leaking_1s_very_d@angerous
题目:
e = 65537 n = 156808343598578774957375696815188980682166740609302831099696492068246337198792510898818496239166339015207305102101431634283168544492984586566799996471150252382144148257236707247267506165670877506370253127695314163987084076462560095456635833650720606337852199362362120808707925913897956527780930423574343287847 c = 108542078809057774666748066235473292495343753790443966020636060807418393737258696352569345621488958094856305865603100885838672591764072157183336139243588435583104423268921439473113244493821692560960443688048994557463526099985303667243623711454841573922233051289561865599722004107134302070301237345400354257869 dp = 734763139918837027274765680404546851353356952885439663987181004382601658386317353877499122276686150509151221546249750373865024485652349719427182780275825
解密脚本:
import gmpy2 e = 65537 n = 156808343598578774957375696815188980682166740609302831099696492068246337198792510898818496239166339015207305102101431634283168544492984586566799996471150252382144148257236707247267506165670877506370253127695314163987084076462560095456635833650720606337852199362362120808707925913897956527780930423574343287847 c = 108542078809057774666748066235473292495343753790443966020636060807418393737258696352569345621488958094856305865603100885838672591764072157183336139243588435583104423268921439473113244493821692560960443688048994557463526099985303667243623711454841573922233051289561865599722004107134302070301237345400354257869 dp = 734763139918837027274765680404546851353356952885439663987181004382601658386317353877499122276686150509151221546249750373865024485652349719427182780275825 for x in range(1, e): if(e*dp%x==1): p=(e*dp-1)//x+1 if(n%p!=0): continue q=n//p phin=(p-1)*(q-1) d=invert(e, phin) m=powmod(c, d, n) if(len(hex(m)[2:])%2==1): continue print("m:",m) #print(hex(m)[2:]) print("flag:",bytes.fromhex(hex(m)[2:]))
最新回复(0)