言語:日本語

tools / rsa

rsa/

RSA の公開鍵で暗号化して秘密鍵で復号、秘密鍵で暗号化して公開鍵で復号もできます。パディング、鍵形式、入出力形式、文字コードを選べ、鍵はブラウザの外に出ません。

平文

鍵

暗号文

履歴

暗号化・復号に成功するたびに自動で記録し、最新 20 件をこの端末のブラウザだけに保存します。鍵は保存しませんが、復号した平文は保存されるので、共用パソコンでは使い終わったら履歴を消去してください。

AES・DES・RSA とは? その違い

AES と DES は共通鍵暗号です。暗号化と復号に同じ鍵を使い、1 本の鍵でドアを閉めて開けるようなものです。高速で大量のデータに向いていますが、その鍵をどうやって安全に相手へ渡すかが課題になります。

DES は 1970 年代の古い標準で、実質的な鍵長は 56 ビットしかなく、今では専用ハードウェアやコンピューター群で総当たり解読できます。まだ DES を使う古いシステムとの連携専用です。AES は DES に代わる標準で、鍵は 128・192・256 ビット。現在、現実的な解読方法はなく、データ暗号化の第一候補です。

RSA は公開鍵暗号です。鍵はペアになっていて、公開鍵は誰に渡してもよく暗号化に使い、秘密鍵は自分だけが持って復号に使います。誰でも手紙を入れられて、自分だけが鍵で開けられる郵便受けのようなものです。事前に鍵を取り決める必要はありませんが、遅く、一度に数百バイトしか暗号化できません。実際のシステムでは両方を組み合わせ、ランダムに作った AES 鍵を RSA で暗号化して相手に送り、本体のデータは AES で暗号化するのが一般的です。

一度に暗号化できる長さ

RSA が一度に暗号化できるのは短いデータだけで、上限は鍵長とパディングで決まります。PKCS1Padding では鍵のバイト数から 11 を引いた値で、2048 ビット鍵なら 245 バイト。OAEP では鍵のバイト数からハッシュ長の 2 倍と 2 を引いた値で、2048 ビット鍵と SHA-256 なら 190 バイトです。長いデータは通常 AES で暗号化し、その AES 鍵を RSA で暗号化します。

Java の書き方との対応

パディング名は Java の Cipher と同じです。RSA/ECB/PKCS1Padding なら PKCS1Padding、RSA/ECB/OAEPWithSHA-256AndMGF1Padding なら 3 番目を選びます(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 の 4 種類に対応し、中身の Base64 だけを貼り付けても使えます。hex は同じ内容を 16 進数にしたものです。パスワード付きの秘密鍵は先に復号してください。鍵の種類が公開鍵でも秘密鍵を貼り付けられ、その公開鍵部分が使われます。

よくある質問

復号で「鍵が対応していない、鍵の種類かパディングが違う」と表示されたらどうしますか?

次の 3 点を順に確認してください。1 つ目は、鍵が暗号化に使った公開鍵と対になっているかどうかです。公開鍵で暗号化した内容は、対応する秘密鍵でしか開けません。2 つ目は、鍵の種類を秘密鍵にすることです。3 つ目は、パディングが暗号化側と一致していることで、OAEPPadding の場合は OAEP ハッシュと MGF1 ハッシュも暗号化側と同じにします。最後に入力形式を確認してください。hex と base64 を取り違えても復号に失敗します。

鍵の形式が違うと表示される、または CERTIFICATE に対応していないと表示されたらどうしますか?

まず「鍵の形式」が貼り付けた内容と合っているか確認してください。-----BEGIN で始まるものは pem、長い 16 進数の文字列は 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 では日本語や中国語の文字 1 文字が 3 バイトなので約 81 文字、文字コードを GBK にすると漢字 1 文字は 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 にだけ保存され、アップロードはされません。ページのコードにも通信処理はありません。暗号化または復号に成功するたびに 1 件記録され、最大 20 件まで保持されます。入力か結果が 2 万文字を超えるものは記録されません。記録にはパラメータ・入力・結果と、鍵から計算した 8 文字のフィンガープリント(モジュラスの SHA-256 の先頭 8 文字で、各記録の # の後ろに表示され、同じ鍵かどうかの判別に使います)が含まれますが、鍵そのものは保存されないため、「読み込む」を押したあとは鍵を貼り付け直す必要があります。復号した平文は保存されるので、共用パソコンでは使い終わったら「履歴を消去」を押してください。