2

Java で RSA 暗号化/復号化を使用しているときに、非常に特殊な問題に直面しています。

コード例:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();

Cipher enc = Cipher.getInstance("RSA");
enc.init(Cipher.ENCRYPT_MODE, kp.getPublic());
String CipherText = new String(enc.doFinal(PlainText.getBytes()));
System.out.println("CipherText: ") + CipherText);

Cipher dec = Cipher.getInstance("RSA");
dec.init(Cipher.DECRYPT_MODE, kp.getPrivate());
PlainText = new String(dec.doFinal(CipherText.getBytes()));
System.out.println("PlainText: " + PlainText);

誰もがはっきりとわかるように、公開鍵を使用して平文を暗号化し、その後、秘密鍵を使用して暗号文を復号化します。

このコードは、次のメッセージでクラッシュします。

Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero

また、「RSA/ECB/NoPadding」を明示的に使用しようとしましたが、これはデコード期間に失敗します。(たとえば、デコードされた暗号文は元の平文と一致しません)。

最後になりましたが、PKCS1.5仕様で独自のPKCS1.5パディング関数を使用するときにこれを実行しようとしました:

EMB = 00 || 02 || RD || 00 || MD
EMB は長さ k のエンコードされたメッセージ ブロックです。RD
は 8 つのランダムな非ゼロ バイト
です。MD は最大長 k = 11 であり、EMB の長さ k を作成するためにオプションでゼロ バイトが埋め込まれます。

2 日間のテストを行った結果、Java の RSA アルゴに欠陥があるか、単に期待どおりに機能していないという結論しか得られません。

上記のコードが期待どおりに機能しない理由に完全に困惑しているため、上記のコードに対する提案や修正は大歓迎です。

4

1 に答える 1

2

これをしないでください:

String CipherText = new String(enc.doFinal(PlainText.getBytes()));

2 つの理由:

  • エンコーディングを指定せずに呼び出すことは、ほとんど良い考えではありません。String.getBytes()結果をシステムのデフォルトのエンコーディングに依存させたいですか?
  • バイナリ暗号化操作の結果 (つまり、不透明なバイナリ データ) をエンコードされた文字列として扱うことは、決して良い考えではありません。代わりに、Base64 または 16 進数でエンコードしてください。

Apache Commons Codecを使用して base64 エンコード/デコード操作を実行するか、このスタンドアロンのパブリック ドメイン エンコーダー/デコーダーを使用できます。

于 2011-05-27T09:16:41.343 に答える