Skip to main content

密碼系統 RSA 攻防

9 min2,335 words

簡介

NIST美國國家標準與科技機構發起的Public Key公開金鑰加解密系統競賽,RSA (Rivest–Shamir–Adleman)加密演算法由三位密碼學家共同研究出來在1973年發表,最終獲選最早為公開金鑰系統標準之一,雖然後來英國Government Communications Headquarters(GCHQ)國家通訊總部說他們的英國密碼學家早在1970年就已經研究出Non-Secret Encryption這種非對稱式加解密系統,但不管怎麼說,RSA在當時算是非常突破性的成果。

金鑰產生 Key generation

首先選擇兩個隨機的大質數ppqq,通常教科書或老師說要取大質數

那怎樣的質數才算大?

參考整數複雜度量測之後討論都使用多少bit長度為單位,以及ppqq這兩個大質數的長度要很接近,用來計算nn: n=pqn = pq 並且 φ(n)=(p1)(q1)\varphi(n) = (p-1)(q-1),如上所說挑選出來的是len(p1q1)len(p-1 \cdot q-1)的長度。

φ(n)\varphi(n)可以參考Euler’s Totient Function尤拉函數,目的是為了找所有與nn互質的數,ppqq挑質數的原因在於在pp之下,每一個數都會跟pp互質,同樣的在qq之下每一個數也都會跟qq互質,這樣乘出來nn群的範圍就會是最大的。

接著隨機挑選一個eZne \in Z_{n}並且eφ(n) e\perp\varphi(n),這個ee之後就會用來當作公鑰,接著使用公鑰計算私鑰dd:

d=e1modφ(n)d = e^{-1} \>\> mod \>\> \varphi(n)dd就是ee的乘法反元素,如此一來,公鑰就是pk=(e,n)pk = (e, n),而私鑰就是sk=(d,n)sk = (d, n)

加密

選一個想要加密的明文Message mZnm \in Z_{n} :

c=E(pk,m)=memodnc = E(pk, m) = m^{e} \>\> mod \>\> n: 加密時使用接收者的公鑰進行加密。

解密 Decryption

接收者收到傳輸者加密過後的密文 Ciphertext cZnc \in Z_{n} :

m=D(sk,c)=cdmodnm = D(sk, c) = c^{d} \>\> mod \>\> n: 解密時接者者使用只有自己知道的私鑰進行解密。

正確性 Correctness

私鑰是由公鑰所計算得來的d=e1modφ(n)d = e^{-1} \>\> mod \>\> \varphi(n),可以調換成ed=kφ(n)+1ed = k\varphi(n)+1,原因是使用費馬小定理Fermat’s Little Theorem:

ap11(modp)a^{p-1} \equiv 1 \>\> (mod \>\> p)aZpa \in Z_{p}為非零整數,pp為質數。

以及中國餘式定理Chinese Remainder Theorem:

如果x=a(modp)x = a \>\> (mod\>\> p)以及x=a(modq)x = a \>\>(mod\>\> q)代表x=a(modpq)x = a \>\>(mod\>\> pq)pqpq為互質的兩數。

所以需要證明的是m=cd(modn)=(memodn)dmodn=medmodnm = c^{d} \>\> (mod \>\> n) = (m^{e} \>\> mod \>\> n)^{d} \>\> mod \>\> n = m^{ed} \>\> mod \>\> n

如前面中國餘式定理所述m=cd(modn)m = c^{d} \>\>(mod\>\> n)可以拆成m=cd(modp)m = c^{d} \>\>(mod\>\> p)以及m=cd(modq)m = c^{d} \>\>(mod\>\> q)使得cd=med(modp)c^{d} = m^{ed} \>\>(mod \>\> p)可以成立,再者ed=1(modφ(n))ed = 1 \>\>(mod \>\> \varphi(n))使得ed=1(mod(p1)(q1))ed = 1 \>\>(mod \>\>(p-1)(q-1))

可以將ed=1(mod(p1)(q1))ed = 1 \>\>(mod \>\>(p-1)(q-1))在modular運算看成ed=k(p1)(q1)+1ed = k(p-1)(q-1) + 1kk必須大於0。

med=mk(p1)(q1)+1(modp)=mmk(p1)(q1)(modp)=m(m(p1))k(q1)(modp)(FermatsLittleTheorem)=m(1)k(q1)(modp)=m(modp)m^{ed}\\ = m^{k(p-1)(q-1)+1} \>\>(mod\>\> p)\\ = m \cdot m^{k(p-1)(q-1)} \>\>(mod \>\>p)\\ = m \cdot (m^{(p-1)})^{k(q-1)} \>\>(mod\>\> p) \>\> \>\> (Fermat's\>\> Little \>\>Theorem)\\ = m \cdot (1)^{k(q-1)} \>\>(mod \>\>p)\\ = m \>\>(mod\>\> p)

同理在modqmod \>\> q也可行:

med=mk(p1)(q1)+1(modq)=mmk(p1)(q1)(modq)=m(m(q1))k(p1)(modq)(FermatsLittleTheorem)=m(1)k(p1)(modp)=m(modq)m^{ed}\\ = m^{k(p-1)(q-1)+1} \>\>(mod\>\> q)\\ = m \cdot m^{k(p-1)(q-1)} \>\>(mod \>\>q)\\ = m \cdot (m^{(q-1)})^{k(p-1)} \>\>(mod\>\> q) \>\> \>\> (Fermat's\>\> Little\>\> Theorem)\\ = m \cdot (1)^{k(p-1)} \>\>(mod \>\>p)\\ = m \>\>(mod\>\> q)

得證med=m(modp)m^{ed} = m \>\>(mod \>\>p)以及med=m(modq)m^{ed} = m \>\>(mod\>\> q)所以med=m(modn)=cm^{ed} = m \>\>(mod \>\>n) = c'

RSA加密加速

非對稱式加密系統的安全性都倚靠數學難題,而計算這些金鑰大多使用軟體像是openssl等,當然也有像是特殊的加解密硬體機器可以使用,一台也不便宜,所以幾乎都是企業才會去採購,故網路上的伺服器幾乎都是使用軟體的方法在計算,但在網路上每秒有多少組金鑰對正在產生,而軟體的計算速度也不能太慢,故可以使用一些小方法來提昇效率。

像是使用特殊的ee,通常會是$2^{x}+1$,再將ee轉換成二進制,使用square-multiply algorithm來加快計算速度。

舉例3 = 11(b), 17 = 10001(b), 65537 = 10000000000000001(b)使用 Square and Multiply 演算法 計算c=memodnc = m^{e} \>\> mod \>\> n只需要少量的乘法就可以。

另外就是透過中國餘式定理與同構特性的特性計算m=cdmodnm = c^{d} \>\> mod \>\> n:

首先設定sk=(d1,d2,n,p,q)sk = (d_{1}, d_{2}, n, p, q)其中d1=dmodp1,d2=dmodq1d_{1} = d \>\> mod \>\> p-1, d_{2} = d \>\> mod \>\> q-1

接著預先計算q=q(q1modp)modn\overline{q} = q(q^{-1} \>\> mod \>\> p)\>\> mod\>\> n以及p=p(p1modq)modn\overline{p} = p(p^{-1} \>\> mod \>\> q)\>\> mod \>\> n

就可以計算m1=(cmodp)d1modpm2=(cmodq)d2modqm=(m1q+m2p)modnm_{1} = (c \>\> mod \>\> p)^{d_{1}}\>\> mod \>\> p \\ m_{2} = (c \>\> mod \>\> q)^{d_{2}} \>\> mod \>\> q \\ m = (m_{1}\overline{q} + m_{2} \overline{p}\>\>\>\>) \>\> mod \>\> n

軟體的話可以利用平行運算分別計算m1m_{1}以及m2m_{2}

RSA加密攻擊

弱參數攻擊 Weak Parameter Attack

是假設私鑰dd挑選的值: d<n1/4 d < n^{1/4}以及p1,p+1,q1,q+1p-1, p+1, q-1, q+1沒有挑選大質數以及pq|p - q|數值很小,ppqq很接近的話(n=2048bitsp=1024bits,q=1024bits)(n = 2048\>\> bits \gets p = 1024 \>\> bits, q = 1024 \>\> bits)代表(pq)2/4{(p-q)^{2}}/{4}也會很小,而(p+q)2/4{(p+q)^{2}}/{4}會比 nn 再大一些,至少n=(p+q)2/4(pq)2/4n = {(p+q)^{2}}/{4} - {(p-q)^{2}}/{4},所以p+q/2{p+q}/{2}會比n\lceil \sqrt{n} \rceil大一些。

首先我們計算z=nz = \lceil \sqrt{n} \rceil y=z+i,i0y = z + i, i \geq 0取得這個yy之後看y2ny^{2} - n是不是一個平方數x2x^{2},如果是的話xx有可能會是x=pq/2x = {p-q}/{2},如果xx是一個平方數的話,可以看成是n分解成(xy)(x+y)=pq(x-y)(x+y) = pq

針對弱參數的對策就是pp的bit數應該要比qq在少一些,不能夠讓bit數太接近。

共同模數攻擊 Common Modulus Attack

假設一組n=pqn = pq用來產生兩對金鑰給兩個使用者:

(pk1,sk1)=((e1,n),(d1,n))(pk2,sk2)=((e2,n),(d2,n))(pk_{1}, sk_{1}) = ((e_{1}, n), (d_{1}, n)) \\ (pk_{2},sk_{2}) = ((e_{2}, n), (d_{2}, n))

可以使用其中一對的金鑰去搜尋另一對的金鑰,假設今天知道user1的金鑰要猜user2的私鑰:

(pk1,sk1,pk2)sk2=(d2,n),d2=e21mod(e1d11)(pk_{1}, sk_{1}, pk_{2}) \to sk_{2}' = (d_{2}', n), d_{2}' = e_{2}^{-1} \>\> mod \>\> (e_{1}d_{1} -1)e1d11e_{1}d_{1}-1就是kφ(n)k \cdot \varphi(n)

以及假設一個MessagemMessage \>\>m同時被這兩個使用者加密,竊聽者可以取得c1=me1modnc_{1} = m^{e_{1}} \>\> mod \>\> nc2=me2modnc_{2} = m^{e_{2}} \>\> mod \>\> n,可以計算s,ts, t用來:

c1sc2tmodn=mse1+te2modn=mc_{1}^{s}c_{2}^{t} \>\> mod \>\> n = m^{se_{1}+te_{2}} \>\> mod \>\> n = m,當然先決條件是:

se1+te2=1se_{1}+te_{2} = 1,並且e1e2e_{1} \perp e_{2}

針對共同模數攻擊的對策是盡量不要使用同一個nn群產生太多把金鑰對,以及盡量不要加密同一個明文太多次。

低指數攻擊 Low Exponent Attack

在早期許多伺服器使用e=3e = 3當作公開金鑰,但風險就是如果mm只要被三個使用者用e=3e=3來加密的話,竊聽者可以取得這些密文cc:

c1=m3modn1c2=m3modn2c3=m3modn3c_{1} = m^{3} \>\> mod \>\> n_{1} \\ c_{2} = m^{3} \>\> mod \>\> n_{2} \\ c_{3} = m^{3} \>\> mod \>\> n_{3}

前面提到使用中國餘式定理CRT可以計算共同的數,c=c1c2c3modn=m3modn1n2n3=m3c = c_{1}c_{2}c_{3} \>\> mod \>\> n = m^{3} \>\> mod \>\> n_{1}n_{2}n_{3} = m^{3}

m=c1/3=(m3)1/3m = c^{1/3} = (m^{3})^{1/3}使用三次方根演算法就能快速解開取得mm了,針對低指數攻個的對策就是ee不要挑選太小

選定密文攻擊 Chosen Ciphertext Attack

這種攻擊方法需要倚靠Oracle讓攻擊者可以取得明文密文對,可以將oracle想成一張很大的表,系統提供一個Decryption Oracle Oe,nO_{e, n}給這oracle一個使用者自己挑選的密文cc,oracle會回傳一個m=cdmodnm = c^{d} \>\> mod \>\> n,唯一的限制就是攻擊者不能要求解開真正想知道的明文密文對,攻擊者只能挑選想破解的密文之外的其他密文,擁有解密oracle後攻擊者要如何攻擊?

透過原本的cc關聯性計算c=cremodnc' = cr^{e} \>\> mod \>\> nrRZn r \in_{R} Z_{n}^{*}

詢問oracle Oe,n(c)mO_{e, n}(c') \to m',這個m=mrm' = m \cdot r

最後計算mr1modn=mrr1modn=mm'r^{-1} \>\> mod \>\> n = mrr^{-1} \>\> mod \>\> n = m

透過mask掉原本的cc得到cc'拿去詢問oracle後再使用攻擊者自己挑選的rr還原得到想要攻擊的ccmm,而這種選定密文攻擊有兩種型態:

  1. Non-adaptive chosen ciphertext attakc(CCA1): 攻擊者把想要詢問的密文一次挑選出來,只能針對oracle詢問一次Oe,n(ci),1isO_{e, n}(c_{i}), 1 \leq i \leq s,無法依靠上一次詢問的結果來調整下一次詢問的選擇
  2. Adaptive chosen ciphertext attack(CCA2): 攻擊者在多項式時間內可以一次一次的詢問oracle,不限詢問次數Oe,n(ci),1isO_{e, n}(c_{i}), 1 \leq i \leq s,可以透過前一次的詢問來調整下一次的詢問選擇。

如此可見CCA2的安全性等級是最高的,所以看paper在證明密碼系統的安全性時雖然作者會寫有CCA的安全性,但需要讀者再去檢查一下oracle的等級,看是達到CCA1還是CCA2的安全性

針對RSA選定密文攻擊方法是採用OAEP+OAEP^{+}使用random oracle model來抵抗CCA2的攻擊

...的公鑰進行驗證 $$Verify(pk, s, m) = ok$$ 如果資訊內容正確就回傳 ok,反之如果簽章是錯的,或者驗證到不匹配的公鑰跟簽章通常會回傳 False、None 或 $\perp$,根據設計者的想法而定 但近代更常見的不是對資訊本身做簽章,而是先將資訊內容做密碼學雜湊函數做計算,得到一組雜湊值再進行簽章,像是著名的...

Referenced in this post