サーバーに送信する長い文字列を暗号化するためにrsaキーを使用しています(サーバーの公開キーと秘密キーで暗号化します)が、これjavax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
までrsaの動作を正しく理解していないと感じるような例外がスローされます(組み込みライブラリを使用することがこれの原因です)。
誰かがこの例外がスローされる理由を説明できますか?暗号化された長い文字列を送信することはまったく不可能ですか?
5 に答える
RSAアルゴリズムは、ビット単位のRSAキー長の最大バイト長を8マイナス11パディングバイトで割ったデータのみを暗号化できます。つまり、最大バイト数=ビット単位のキー長/8-11です。
したがって、基本的には、キーの長さを8 -11で除算します(パディングがある場合)。たとえば、2048ビットのキーがある場合は、2048/8 = 256バイト(パディングがある場合は-11バイト)を暗号化できます。したがって、より大きなキーを使用するか、対称キーを使用してデータを暗号化し、そのキーをrsaを使用して暗号化します(これが推奨されるアプローチです)。
それには、次のことが必要になります。
- 対称鍵を生成する
- 対称鍵を使用してデータを暗号化する
- 対称鍵をrsaで暗号化する
- 暗号化されたキーとデータを送信します
- 暗号化された対称鍵をrsaで復号化します
- 対称鍵を使用してデータを復号化する
- 終わり :)
秘密のデータに RSA を直接使用しないでください。セッションキーやメッセージ認証コードなど、疑似ランダムまたは完全にランダムなデータに対してのみ RSA を使用する必要があります。
256 バイトで問題が発生しました。これは、おそらく 2048 ビット キーを使用しているためです。キーは範囲内の任意の整数を同じ範囲に暗号化でき0
ます2^2048 - 1
。つまり、データは 256 バイト以下である必要があります。
これ以上の暗号化を行う場合は、1 つの RSA 暗号化を使用して対称アルゴリズムのセッション キーを暗号化し、それを使用してデータを暗号化してください。
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);
}