RSA 选择明密文攻击
选择明文攻击
这里给出一个例子,假如我们有一个加密 oracle ,但是我们不知道 n 和 e,那
我们可以通过加密 oracle 获取 n。
在 e 比较小( $e<2^{64}$)时,我们可以利用 Pollard’s kangaroo algorithm 算法获取 e。这一点比较显然。
我们可以加密 2,4,8,16。那么我们可以知道
$c_2=2^{e} \bmod n$
$c_4=4^{e} \bmod n$
$c_8=8^{e} \bmod n$
那么
$c_2^2 \equiv c_4 \bmod n$
$c_2^3 \equiv c_8 \bmod n$
故而
$c_2^2-c_4=kn$
$c_2^3-c_8=tn$
我们可以求出 kn 和 tn 的最大公因数,很大概率就是 n 了。我们还可以构造更多的例子从来更加确定性地找 n。
任意密文解密
假设爱丽丝创建了密文 $C = P^e \bmod n$ 并且把 C 发送给鲍勃,同时假设我们要对爱丽丝加密后的任意密文解密,而不是只解密 C,那么我们可以拦截 C,并运用下列步骤求出 P:
选择任意的 $X\in Z_n^{*}$,即 X 与 N 互素
计算 $Y=C \times X^e \bmod n$
由于我们可以进行选择密文攻击,那么我们求得 Y 对应的解密结果 $Z=Y^d$
那么,由于 $Z=Y^d=(C \times X^e)^d=C^d X=P^{ed} X= P X\bmod n$,由于 X 与 N 互素,我们很容易求得相应的逆元,进而可以得到 P
RSA parity oracle
假设目前存在一个 Oracle,它会对一个给定的密文进行解密,并且会检查解密的明文的奇偶性,并根据奇偶性返回相应的值,比如 1 表示奇数,0 表示偶数。那么给定一个加密后的密文,我们只需要 log(N) 次就可以知道这个密文对应的明文消息。
原理
假设
$C=P^e \bmod N$
第一次时,我们可以给服务器发送
$C*2^e=(2P)^e \bmod N$
服务器会计算得到
$2P \bmod N$
这里
2P 是偶数,它的幂次也是偶数。
N 是奇数,因为它是由两个大素数相乘得到。
那么
服务器返回奇数,即 $2P \bmod N$ 为奇数,则说明 2P 大于 N,且减去了奇数个 N,又因为 $2P<2N$,因此减去了一个N, 即 $\frac{N}{2} \leq P < N$,我们还可以考虑向下取整。
服务器返回偶数,则说明 2P 小于 N。即 $0\leq P < \frac{N}{2}$,我们还可以向下取整。
这里我们使用数学归纳法,即假设在第 i 次时,$\frac{xN}{2^{i}} \leq P < \frac{xN+N}{2^{i}}$
进一步,在第 i+1 次时,我们可以发送
$C*2^{(i+1)e}$
服务器会计算得到
$2^{i+1}P \bmod N=2^{i+1}P-kN$
$0 \leq 2^{i+1}P-kN<N$
$\frac{kN}{2^{i+1}} \leq P < \frac{kN+N}{2^{i+1}}$
根据第 i 次的结果
$\frac{2xN}{2^{i+1}} \leq P < \frac{2xN+2N}{2^{i+1}}$
那么
服务器返回奇数,则 k 必然是一个奇数,k=2y+1, 那么 $\frac{2yN+N}{2^{i+1}} \leq P < \frac{2yN+2N}{2^{i+1}}$。与此同时,由于 P 必然存在,所以第 i+1 得到的这个范围和第 i 次得到的范围必然存在交集。所以 y 必然与 x 相等。
服务器返回偶数,则 k 必然是一个偶数,k=2y,此时 y 必然也与 x 相等,那么 $\frac{2xN}{2^{i+1}} \leq P < \frac{2xN+N}{2^{i+1}}$
进一步我们可以这么归纳
这里虽然是整除, 即下取整,但是无所谓我们在最初时已经分析了这个问题。
2018 Google CTF Perfect Secrecy
这里以 2018 年 Google CTF 的题目为例进行分析
可以看出
我们可以给服务器两个数,服务器会根据解密后的密文内容来决定使用哪一个。
服务器会使用
random.randint(0, 2)来生成随机数,并输出相关的随机 01 字节 c。
乍一看,似乎是完全随机的,仔细查一下 random.randint(0, 2) 可以知道其生成随机数是包括边界的,因此其生成偶数的概率大于生成奇数的概率,那么 c 与 p 同奇偶的概率为 2/3。进而我们通过设置 m0 和 m1 就可以知道解密后的密文的最后一位是 0 还是 1 。这其实就是 RSA parity oracle。
exp 如下
结果如下
解码后就可以得到 flag
题目
2016 Plaid CTF rabit
2016 sharif CTF lsb-oracle-150
2018 Backdoor CTF BIT-LEAKER
2018 XMAN 选拔赛 baby RSA
RSA Byte Oracle
假设目前存在一个 Oracle,它会对一个给定的密文进行解密,并且会给出明文的最后一个字节。那么给定一个加密后的密文,我们只需要 $\log_{256}n$ 次就可以知道这个密文对应的明文消息。
原理
这个其实算作 RSA parity Oracle 的扩展,既然可以泄露出最后一个字节,那么按道理我们获取密文对应明文的次数应该可以减少。
假设
$C=P^e \bmod N$
第一次时,我们可以给服务器发送
$C*256^e=(256P)^e \bmod N$
服务器会计算得到
$256P \bmod N$
这里
256P 是偶数。
N 是奇数,因为它是由两个大素数相乘得到。
由于 P 一般是小于 N 的,那么$256P \bmod N=256P-kn, k<256$。而且对于两个不同的 $k_1,k_2$,我们有
$256P-k_1n \not\equiv 256P-k_2n \bmod 256$
我们可以利用反证法来证明上述不等式。同时 $256P-kn$ 的最后一个字节其实就是 $-kn$ 在模 256 的情况下获取的。那么,其实我们可以首先枚举出 0~255 情况下的最后一个字节,构造一个 k 和最后一个字节的映射表 map
当服务器返回最后一个字节 b,那么我们可以根据上述构造的映射表得知 k,即减去了 k 个N, 即 $kN \leq 256 P \leq (k+1)N$。
此后,我们使用数学归纳法来获取 P 的范围,即假设在第 i 次时,$\frac{xN}{256^{i}} \leq P < \frac{xN+N}{256^{i}}$
进一步,在第 i+1 次时,我们可以发送
$C*256^{(i+1)e}$
服务器会计算得到
$256^{i+1}P \bmod N=256^{i+1}P-kN$
$0 \leq 256^{i+1}P-kN<N$
$\frac{kN}{256^{i+1}} \leq P < \frac{kN+N}{256^{i+1}}$
根据第 i 次的结果
$\frac{256xN}{256^{i+1}} \leq P < \frac{256xN+256N}{256^{i+1}}$
我们这里可以假设 $k=256y+t$, 而这里的 t 就是我们可以通过映射表获取的。
$\frac{256yN+tN}{256^{i+1}} \leq P < \frac{256yN+(t+1)N}{256^{i+1}}$
与此同时,由于 P 必然存在,所以第 i+1 得到的这个范围和第 i 次得到的范围必然存在交集。
所以 y 必然与 x 相等。
进一步我们可以这么归纳,初始情况下
假设服务器返回了 b,那么
2018 HITCON lost key
这是一个综合题目,首先没有给出 n,我们可以使用选择明文攻击的方式获取 n,当然我们也可以进一步获取 e,最后利用代码如下
RSA parity oracle variant
原理
如果oracle的参数会在一定时间、运行周期后改变,或者网络不稳定导致会话断开、重置,二分法就不再适用了,为了减少错误,应当考虑逐位恢复。 要恢复明文的第2低位,考虑
{(c(2−1∗e1modN1))d1modN1}(mod2)≡m∗2−1
类似的
{(c(2−2∗e2modN2))d2modN2}(mod2)≡m∗2−2
我们就可以使用前i-1位与oracle的结果来得到第i位。注意这里的$2^{-1}$是$2^1$模$N_1$的逆元。所以对剩下的位,有
其中$2^{-i}$是$2^i$模$N_i$的逆元。
就可以逐步恢复原文所有的位信息了。这样的时间复杂度为$O(logm)$。
exp:
参考
https://crypto.stackexchange.com/questions/11053/rsa-least-significant-bit-oracle-attack
https://pastebin.com/KnEUSMxp
https://github.com/ashutosh1206/Crypton
Last updated