58

サーバーに送信する長い文字列を暗号化するためにrsaキーを使用しています(サーバーの公開キーと秘密キーで暗号化します)が、これjavax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes までrsaの動作を正しく理解していないと感じるような例外がスローされます(組み込みライブラリを使用することがこれの原因です)。
誰かがこの例外がスローされる理由を説明できますか?暗号化された長い文字列を送信することはまったく不可能ですか?

4

5 に答える 5

85

RSAアルゴリズムは、ビット単位のRSAキー長の最大バイト長を8マイナス11パディングバイトで割ったデータのみを暗号化できます。つまり、最大バイト数=ビット単位のキー長/8-11です。

したがって、基本的には、キーの長さを8 -11で除算します(パディングがある場合)。たとえば、2048ビットのキーがある場合は、2048/8 = 256バイト(パディングがある場合は-11バイト)を暗号化できます。したがって、より大きなキーを使用するか、対称キーを使用してデータを暗号化し、そのキーをrsaを使用して暗号化します(これが推奨されるアプローチです)。

それには、次のことが必要になります。

  1. 対称鍵を生成する
  2. 対称鍵を使用してデータを暗号化する
  3. 対称鍵をrsaで暗号化する
  4. 暗号化されたキーとデータを送信します
  5. 暗号化された対称鍵をrsaで復号化します
  6. 対称鍵を使用してデータを復号化する
  7. 終わり :)
于 2012-04-04T08:14:37.343 に答える
15

秘密のデータに RSA を直接使用しないでください。セッションキーやメッセージ認証コードなど、疑似ランダムまたは完全にランダムなデータに対してのみ RSA を使用する必要があります。

256 バイトで問題が発生しました。これは、おそらく 2048 ビット キーを使用しているためです。キーは範囲内の任意の整数を同じ範囲に暗号化でき0ます2^2048 - 1。つまり、データは 256 バイト以下である必要があります。

これ以上の暗号化を行う場合は、1 つの RSA 暗号化を使用して対称アルゴリズムのセッション キーを暗号化し、それを使用てデータを暗号化してください。

于 2012-04-04T08:37:22.527 に答える
-3

publicKey でデータを分割する必要があります

int keyLength = publicKey.getModulus().bitLength() / 16;
String[] datas = splitString(data, keyLength - 11);
String mi = ""//the data after encrypted;
for (String s : datas) {
    mi += bcd2Str(cipher.doFinal(s.getBytes()));
}
return mi;


public static String bcd2Str(byte[] bytes) {
    char temp[] = new char[bytes.length * 2], val;

    for (int i = 0; i < bytes.length; i++) {
        val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
        temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

        val = (char) (bytes[i] & 0x0f);
        temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
    }
   return new String(temp);
}
于 2016-07-19T03:26:42.563 に答える