tools / rsa
rsa/
RSA 公鑰加密、私鑰解密,也能私鑰加密、公鑰解密。填補方式、金鑰格式、輸入輸出格式和字元集都可以選擇,金鑰不會離開瀏覽器。
明文
金鑰
密文
歷史紀錄
每次加密、解密成功後會自動記錄一筆,保留最近 20 筆,只存在這台裝置的瀏覽器裡。不會儲存金鑰,但解密出的明文會被儲存,在公用電腦上使用完請清除紀錄。
AES、DES、RSA 是什麼,有什麼差別
AES 和 DES 是對稱式加密:加密和解密用同一把金鑰,就像同一把鑰匙既能鎖門也能開門。它們速度快,適合加密大量資料,難處在於要怎麼把這把金鑰安全地交給對方。
DES 是 1970 年代的老標準,有效金鑰只有 56 位元,現在用專用硬體或電腦叢集就能暴力破解,只適合用來串接仍在使用它的舊系統。AES 是取代 DES 的新標準,金鑰長度為 128、192 或 256 位元,目前沒有可行的破解方法,是現在加密資料的首選。
RSA 是非對稱式加密:有一對金鑰,公鑰可以公開給任何人,用來加密;私鑰自己保管,用來解密。就像一個誰都能投信、只有你有鑰匙的信箱。好處是不用事先約定金鑰,缺點是很慢,一次只能加密幾百位元組。實際系統常把兩者結合:先用 RSA 加密一把隨機產生的 AES 金鑰傳給對方,再用 AES 加密真正的資料。
一次能加密多長的內容
RSA 一次只能加密一小段資料,上限由金鑰長度和填補方式決定。PKCS1Padding 最多是金鑰位元組數減 11,2048 位元金鑰是 245 位元組;OAEP 最多是金鑰位元組數減去兩倍雜湊長度再減 2,2048 位元金鑰搭配 SHA-256 是 190 位元組。更長的資料通常先用 AES 加密,再用 RSA 加密 AES 金鑰。
和 Java 的寫法怎麼對應
填補方式的名稱與 Java 的 Cipher 一致:RSA/ECB/PKCS1Padding 選 PKCS1Padding;RSA/ECB/OAEPWithSHA-256AndMGF1Padding 選第三項,Java 預設 MGF1 使用 SHA-1;用 OAEPParameterSpec 自訂雜湊時選 OAEPPadding,再分別選擇 OAEP 雜湊和 MGF1 雜湊。字元集也依 Java 的規則,例如 UTF-16 編碼時開頭帶 FE FF、採大端序排列。
為什麼每次加密結果都不一樣
公鑰加密時,PKCS1Padding 和 OAEP 都會在填補中加入亂數,同樣的內容每次加密結果都不同,但都能用私鑰解開,這是正常的。私鑰加密的填補是固定的,結果每次都一樣。OAEP 只能公鑰加密、私鑰解密。
支援哪些金鑰
PEM 支援 BEGIN PUBLIC KEY、BEGIN RSA PUBLIC KEY、BEGIN PRIVATE KEY、BEGIN RSA PRIVATE KEY 四種,也可以只貼上中間的 Base64;hex 是同樣內容的十六進位表示。帶密碼的私鑰需要先解密。金鑰類型選公鑰時也可以直接貼上私鑰,會使用其中的公鑰部分。
常見問題
解密顯示「金鑰不對應、金鑰類型或填補方式不對」怎麼辦
依三項逐一檢查:一是金鑰是否和加密用的公鑰成對,用公鑰加密的內容只能用配對的私鑰解開;二是金鑰類型要選私鑰;三是填補方式要和加密端一致。選 OAEPPadding 時,OAEP 雜湊和 MGF1 雜湊也都要和加密端相同。最後確認輸入格式沒選錯,hex 和 base64 選反也會解密失敗。
金鑰格式不對,或顯示「不支援 CERTIFICATE」怎麼辦
先確認「金鑰格式」和貼上的內容一致:以 -----BEGIN 開頭的選 pem,一長串十六進位的選 hex,選錯時通常會提示應改成哪一個。PEM 裡必須是 RSA 公鑰或私鑰,憑證(BEGIN CERTIFICATE)不能直接使用,可以先用 openssl x509 -in cert.pem -pubkey -noout 取出公鑰。憑證和金鑰貼在一起時,會自動取其中的金鑰區塊。
私鑰帶密碼,顯示「請先解密成不帶密碼的私鑰」怎麼辦
這裡不支援帶密碼的私鑰(BEGIN ENCRYPTED PRIVATE KEY,或 PEM 標頭裡有 Proc-Type: 4,ENCRYPTED),需要先在本機去掉密碼再貼上,例如用 openssl rsa -in 原檔案 -out 新檔案,依提示輸入密碼。去掉密碼後的檔案就等於明文私鑰,用完請妥善處理。
顯示「內容超過上限」,能加密多少個中文字
上限是以位元組計算,不是以字數計算。2048 位元金鑰搭配 PKCS1Padding 最多 245 位元組,UTF-8 下一個中文字佔 3 位元組,約 81 個字;字元集選 GBK 時一個中文字佔 2 位元組,約 122 個。加密時貼上金鑰後,金鑰欄標題旁會顯示目前金鑰和填補方式下「最多加密 N 位元組」。超出時會直接顯示錯誤,這裡不會自動分段加密。
前端 JSEncrypt 或 Web Crypto 加密的結果,這裡怎麼解
JSEncrypt 使用 PKCS1Padding,輸出是 Base64,所以這裡填補方式選 PKCS1Padding,輸入格式選 base64。瀏覽器 Web Crypto 的 RSA-OAEP 用同一個雜湊同時做 OAEP 和 MGF1,這裡要選 OAEPPadding,並把 OAEP 雜湊和 MGF1 雜湊設成相同的值,例如都選 SHA256。兩種情況下金鑰類型都選私鑰。
顯示「密文比金鑰長度還長」或「密文數值超出金鑰範圍」是什麼意思
RSA 密文的長度等於金鑰的位元組數,2048 位元金鑰是 256 位元組,寫成 hex 是 512 個字元,不會更長。解密時金鑰欄標題旁會顯示「密文 N 位元組」,拿它和輸入欄旁的位元組數對照一下。比金鑰還長,多半是輸入格式選錯或多複製了內容;數值超出範圍,表示這段密文不是用這把金鑰配對的公鑰加密的,請換成正確的金鑰。
私鑰加密、公鑰解密可以用來簽章和驗證簽章嗎
不能直接當簽章用。這裡的私鑰加密只是把你輸入的內容依 PKCS1Padding 用私鑰運算,不做雜湊;而 SHA256withRSA 這類簽章是先計算雜湊,再把雜湊依固定結構(DigestInfo)填進去。所以用這裡的公鑰去解一個標準簽章,得到的是這個結構,不是原文。要簽章或驗證簽章,請使用支援 SHA256withRSA 這類演算法的函式庫或工具。
歷史紀錄裡存了什麼,會上傳嗎
只存在這台裝置瀏覽器的 localStorage 裡,不會上傳,頁面程式碼中沒有任何網路請求。每次成功加密或解密後記錄一筆,最多保留 20 筆,輸入或結果超過 2 萬字元的不記錄。紀錄中有參數、輸入和結果,以及一個由金鑰算出的 8 位指紋(模數的 SHA-256 前 8 位,在紀錄中 # 號後面,用來區分是不是同一把金鑰),不儲存金鑰本身,所以點選「填入」後要重新貼上金鑰。解密出的明文會被儲存,在公用電腦上使用完請點選「清除紀錄」。