选择明密文攻击

1.选择明文攻击 :

适用情况:

对输入的任意明文服务器返回 RSA 加密结果。

可以通过选择明文攻击来获取 n。

原理:

H5wGqK.png

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import gmpy2

def get_n():
nset = []
c2 = server_encode(2)
c4 = server_encode(4)
c8 = server_encode(8)
nset.append(c2 * c2 - c4)
nset.append(c2 * c2 * c2 - c8)
c3 = server_encode(3)
c9 = server_encode(9)
c27 = server_encode(27)
nset.append(c3 * c3 - c9)
nset.append(c3 * c3 * c3 - c27)
c5 = server_encode(5)
c25 = server_encode(25)
c125 = server_encode(125)
nset.append(c5 * c5 - c25)
nset.append(c5 * c5 * c5 - c125)
n = nset[0]
for x in nset:
n = gmpy2.gcd(x, n)
while n % 2 == 0:
n /= 2
while n % 3 == 0:
n /= 3
while n % 5 == 0:
n /= 5
print 'n =', n
return n

2.选择密文攻击

适用情况

可以构造任意密文并获得对应明文。

通过选择密文攻击获得特定的明文。

原理:

假设服务器创建了密文 C=M ^ e mod n,并且把 c 发送给用户,用户可以发送任意密文服务器返回解密后的明文。可以通过下面方法求出 M:

  1. 选择任意的 X 与 n 互素。
  2. 计算 Y=C * X ^ e mod n。
  3. 由于可以进行选择密文攻击,那么可以求得 Y 对应的解密结果 Z=Yd。
  4. 则 Z=Y^d =(C*X^e)^d=C^d * X=M * X  mod  n 。由于 X 与 n 互素,很容易求得相应的逆元,进而可以得到 M。

exp:

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import *

def get_M():
X = getPrime(5)
Y = (c * (X ** e)) % n
Z = server_decode(Y)
i = 0
while True:
M = (n * i + Z) / X
if 'flag' in long_to_bytes(M):
print long_to_bytes(M)
break