跳至主要內容
RSA 加密原理

RSA 加密原理

RSA 是一種公開金鑰密碼系統。使用公鑰加密,再以對應的私鑰解密。兩個質數相乘很容易,但從很大的乘積找出原本的質數很困難。這項特性是其安全性的基礎。

公式符號說明

gcd(a, b) 是 a 與 b 的最大公因數,也就是能同時整除兩者的最大正整數。例如,12 與 18 的最大公因數是 6。最大公因數為 1 的兩個數稱為「互質」,但這兩個數本身不一定是質數。

gcd⁡(12,18)=6,gcd⁡(3,40)=1\gcd(12,18) = 6, \qquad \gcd(3,40) = 1

a mod n 是 a 除以 n 的餘數。例如,17 除以 5 的商為 3、餘數為 2。RSA 使用大數冪次除以 n 的餘數,而非完整的冪次值。

17=3×5+2,17 mod 5=217 = 3 \times 5 + 2, \qquad 17 \bmod 5 = 2

a ≡ b (mod n) 表示 a 與 b 分別除以 n 時,餘數相同。例如,17 與 2 除以 5 的餘數都是 2。

17≡2(mod5)17 \equiv 2 \pmod 5

1. 產生文字用金鑰

產生 2048 位元 RSA 金鑰,搭配 OAEP (SHA-256、MGF1-SHA-256 與空標籤)。手算用的小金鑰沒有足夠空間容納 OAEP。金鑰與明文只在瀏覽器內處理。

產生金鑰後,輸入的文字會自動加密與解密。

2. 使用公鑰加密

UTF-8: 13 / 190 位元組

將文字轉為 UTF-8 位元組序列 M,再以 OAEP 產生 256 位元組的編碼資料 EM。OAEP 並非單純補零,而是使用雜湊與 32 位元組的隨機種子。將 EM 轉為整數 m 後使用 RSA 加密。相同文字每次加密都會產生不同的密文。

M=UTF8⁡(text),m=OS2IP⁡(OAEP⁡(M))M = \operatorname{UTF8}(\mathrm{text}),\quad m = \operatorname{OS2IP}(\operatorname{OAEP}(M))
∣M∣=13,∣PS∣=256−13−2×32−2=177|M| = 13,\quad |PS| = 256 - 13 - 2 \times 32 - 2 = 177

PS 是 OAEP 內部的零位元組序列。將它與空標籤的雜湊 (32 位元組)、分隔符號 (1 位元組) 及 M 合併,再以隨機種子衍生的 MGF1 遮罩處理。EM 由開頭的 1 位元組、遮罩後的種子 (32 位元組) 與遮罩後的資料 (223 位元組) 組成。

DB=SHA256⁡(ε) ∥ PS ∥ 01 ∥ MDB = \operatorname{SHA256}(\varepsilon)\,\|\,PS\,\|\,\mathtt{01}\,\|\,M
EM=00 ∥ maskedSeed ∥ maskedDB,c=m65537 mod nEM = \mathtt{00}\,\|\,maskedSeed\,\|\,maskedDB,\quad c = m^{65537}\bmod n

3. 使用私鑰解密

使用私密指數 d 與 n,從密文 c 還原整數 m。將其轉回 256 位元組的 EM,驗證並移除 OAEP 後,再以 UTF-8 解碼還原文字。解密計算不需要公開指數 e。

m=cd mod n,M=OAEPDecode⁡(I2OSP⁡(m,256))m = c^d \bmod n,\quad M = \operatorname{OAEPDecode}(\operatorname{I2OSP}(m,256))

4. PEM 格式與 OpenSSL 指令

以下 OpenSSL 3 範例會另外產生一組 2048 位元金鑰,並使用 OAEP (SHA-256)。此金鑰大小最多可加密 190 位元組的明文;較長的資料應搭配對稱式加密。

產生金鑰並匯出公鑰

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem

先將明文儲存為 message.txt,再依序執行下列指令。private.pem 是未加密的私鑰,必須妥善保管。

使用公鑰加密檔案

openssl pkeyutl -encrypt -pubin -inkey public.pem -in message.txt -out encrypted.bin -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256

使用私鑰解密檔案

openssl pkeyutl -decrypt -inkey private.pem -in encrypted.bin -out decrypted.txt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256

原始明文會輸出至 decrypted.txt。OAEP 使用隨機值,因此相同明文每次加密都會產生不同的密文。

OpenSSL 官方文件