1. 程式人生 > >RSA 時序攻擊

RSA 時序攻擊

initial 難度 cnblogs 配置 解密 循環 blocking 有一個 targe

RSA的破解從理論上來講是大數質數分解,可是就是有一些人另辟蹊徑,根據你解密的時間長短就能破解你的RSA私鑰。

舉一個不恰當但是比較容易理解的例子:

密文0101

私鑰0110

明文0100

問題的關鍵來了,進行&運算時如果有一個0,那麽運算的時間為1ms,如果兩個都是1,運算的時間是10ms(只是個假設)。

基於以上假設,就可以破解私鑰了。先構造一個0001的密文,獲取解密的時間,如果是1ms左右,那麽對應的位就是0,

如果是10ms左右,對應的1,依次類推,就把整個私鑰推斷出來了。

如何防範這種攻擊呢?

一種最簡單有效的方法,每次過來一個密文,先用一個隨機數與它&一下,然後再與私鑰&,只要隨機數是真正的隨機數,那麽

是無法破解的。註意,是真正的隨機數而不是偽隨機數。

RSA解密的本質就是冪模運算,也就是x = a ^ b mod n ,其中a是明文,b是私鑰,n是兩個大質數(p-1)(q-1)的積。由於這些

數都特別大,比如b可能有2048位,直接計算是不可行的。計算x的最經典的算法是蒙哥馬利算法,用代碼表示如下:

int mod(int a,int b,int n){  
    int result = 1;  
    int base = a;  
    while(b>0){  
     if(b & 1==1){  
         result = (result*base) % n;  
      }  
     base 
= (base*base) %n; b>>=1; } return result; }

這個算法從b的最低位循環到最高位,如果是1,需要進行兩次模乘運算,如果是0的話則只需要一次。由於這個操作是比較耗時的,所以

0和1對應的時間差別較大。攻擊者可以通過觀察不同輸入對應的解密時間,通過分析統計推斷出私鑰。而防範RSA時序攻擊的方法也是在

解密時加入隨機因素,讓攻擊者無法獲取準確的解密時間。

關於隨機數

真正意義上的隨機數,是很難產生的,因為即使小到原子,它的規律也是有跡可循的。所以我們產生的隨機數都是偽隨機數,但是偽隨機數的

隨機性也是不一樣的,如果產生的隨機數規律性很強,那就很容易被預測到,而如果產生的隨機數被預測的難度特別大,那麽我們就可以認為

它是真隨機數了,只有強度高的隨機數用來加解密等操作上才是安全的。

目前大部分操作系統都會提供兩種隨機數的產生方式,以Linux為例,它提供了/dev/urandom和/dev/random兩個特殊設備,可以從裏面讀

取一定長度的隨機數。

(1)/dev/random是blocking pseudo random number generator (阻塞式偽隨機數產生器),它是通過網絡事件,鍵盤敲

事件等物理上隨機的事件,收集一些隨機bit到熵池來產生隨機數。這個隨機生成函數可能因為熵池為空而等待,所以需要大量隨機數的情

況下它會顯得很慢,但諸如產生證書之類的操作需要這種強度的隨機數。

(2)/dev/urandom就是unblocking,它不會阻塞,但是產生的隨機數不夠高,是以時間戳之類的種子來產生隨機數。

Java可以用SecureRandom產生隨機數,而且可以在JVM參數裏配置是使用/dev/random還是/dev/urandom,如果安全性要求改,就用

/dev/random,但是性能是就會有折扣。

出處:

RSA的那些坑

RSA 時序攻擊