RSA 加密原理
RSA 是一種公開金鑰密碼系統。使用公鑰加密,再以對應的私鑰解密。兩個質數相乘很容易,但從很大的乘積找出原本的質數很困難。這項特性是其安全性的基礎。
公式符號說明
gcd(a, b) 是 a 與 b 的最大公因數,也就是能同時整除兩者的最大正整數。例如,12 與 18 的最大公因數是 6。最大公因數為 1 的兩個數稱為「互質」,但這兩個數本身不一定是質數。
a mod n 是 a 除以 n 的餘數。例如,17 除以 5 的商為 3、餘數為 2。RSA 使用大數冪次除以 n 的餘數,而非完整的冪次值。
a ≡ b (mod n) 表示 a 與 b 分別除以 n 時,餘數相同。例如,17 與 2 除以 5 的餘數都是 2。
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 加密。相同文字每次加密都會產生不同的密文。
PS 是 OAEP 內部的零位元組序列。將它與空標籤的雜湊 (32 位元組)、分隔符號 (1 位元組) 及 M 合併,再以隨機種子衍生的 MGF1 遮罩處理。EM 由開頭的 1 位元組、遮罩後的種子 (32 位元組) 與遮罩後的資料 (223 位元組) 組成。
3. 使用私鑰解密
使用私密指數 d 與 n,從密文 c 還原整數 m。將其轉回 256 位元組的 EM,驗證並移除 OAEP 後,再以 UTF-8 解碼還原文字。解密計算不需要公開指數 e。
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 官方文件