0

以前にも同様の質問があったことは知っていますが、私の問題に固有の回答が見つかりません。RSA 暗号化を使用して、暗号化されたピクセルを含む画像を取得し、同じ秘密鍵を使用して復号化しようとしています。getRGB() を使用して画像のピクセルから取得した int を復号化しようとすると、問題が発生し続けます。ここに私のコードがあります:

int pixel = img.getRGB(1, 1);
System.out.println(pixel);

byte[] bytes = ByteBuffer.allocate(4).putInt(pixel).array();
System.out.println(fromByteArray(bytes));
bytes = rsa.RSADecryptB(privk, bytes);
int nom = ByteBuffer.wrap(bytes).getInt(); // big-endian by default
System.out.println(nom);

これは、別のクラスからメソッド RSADecryptB を呼び出すメイン クラスにあります。そのメソッドは次のとおりです。

public static []byte RSADecryptB(PrivateKey privatekey, byte[] cipherText) {
byte[] ll = null;
  try {
     /* Create cipher for decryption. */
     Cipher decrypt_cipher = Cipher.getInstance("RSA");
     decrypt_cipher.init(Cipher.DECRYPT_MODE, privatekey);


     ll = decrypt_cipher.doFinal(cipherText);

  } catch (IllegalBlockSizeException e) {
     System.out.println("1");
     e.printStackTrace();
  }
  catch (InvalidKeyException et) {
     System.out.println("2");
     et.printStackTrace();
  }
  catch (NoSuchAlgorithmException ev) {
     System.out.println("3");
     ev.printStackTrace();
  }
  catch (BadPaddingException ea) {
     System.out.println("4");
     ea.printStackTrace();
  }
  catch (NoSuchPaddingException eo) {
     System.out.println("5");
     eo.printStackTrace();
  }
  return ll;

}

プログラムを実行すると、出力は次のようになります。

-1606258341
5
4
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at Encryption5.RSADecryptB(Encryption5.java:126)
at ImageEncryptor.main(ImageEncryptor.java:405)
Exception in thread "main" java.lang.NullPointerException
at java.nio.ByteBuffer.wrap(ByteBuffer.java:396)
at ImageEncryptor.main(ImageEncryptor.java:406)

なぜこれが起こっているのかわかりません。-1606258341 はピクセルの値で、5 と 4 の出力は NoSuchPaddingException と BadPaddingException によるものです。なぜこれが起こっているのか、そして私が何を間違っているのかを説明できる人がいれば、それは素晴らしいことです. ありがとう!

編集:おそらくRSAを直接使用すべきではないことはわかっていますが、ピクセルごとに自分で暗号化も行っています。最も効率的で安全なプログラムを作成するためではなく、bufferedimages/byte arrays/rsa を使用して練習するためにこれを行っています。また、暗号化メソッドで整数を復号化すると、正常に機能します。別の方法で復号化すると、エラーが発生します。また、画像を暗号化してファイルに保存し、解凍して復号化します。これも私の暗号化方法です(パディングは使用しません):

 int w = img.getWidth();
     int h = img.getHeight();
     byte[] bytes = null;
     ByteBuffer wrappedo = null;
     int nom = 0;
     ByteBuffer wrapped = null;
     int num = 0;
     int pixel = 0;
System.out.println("width, height: " + w + ", " + h);

for (int i = 0; i < h; i++) {
  for (int j = 0; j < w; j++) {

     pixel = img.getRGB(j, i);

bytes = ByteBuffer.allocate(4).putInt(pixel).array();
bytes = rsa.RSAEncrypt(bytes);
wrappedo = ByteBuffer.wrap(bytes); // big-endian by default
nom = wrappedo.getInt();

img.setRGB(j, i, nom);

}

  } 

次に、RSAEncrypt メソッドを次に示します。

public static byte[] RSAEncrypt(byte[] data) {
byte[] cipherData = null;
try {
PublicKey pubKey = readKeysFromFile();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
cipherData = cipher.doFinal(data);
}
catch (Exception e) {}

return cipherData;
}
4

1 に答える 1

0

イメージの暗号化に使用された方法が必要です。ほとんどの場合、現在期待されている方法で暗号化することはできません。プレーン/生/教科書/おもちゃのRSA(剰余累乗のみ)の場合がありますが、その場合は復号化ルーチンを自分で作成する必要があります.

すべてのピクセルが個別に暗号化されている可能性はほとんどありません。JB Nizet がすでに述べたように、それは非常に非効率的です。RSA 出力はキー ペアのサイズです (これはモジュラスのバイト単位のサイズと同じです)。RSA キー ペアのキー サイズは、復号化を困難にするために最低でも 512 ビット、安全にするためには約 2048 ビットにする必要があります。通常、RSA を使用して大きなテキストを暗号化するには、ハイブリッド スキームが使用されます (たとえば、最初に AES を使用して暗号化し、次に RSA を使用して AES キーを暗号化します)。

さらに、現在"RSA"アルゴリズムとして指定しています。SUNRSA プロバイダー (および他のほとんどのプロバイダー) の場合、これは as に変換さ"RSA/ECB/PKCS1Padding""ECB""PKCS1Padding"デフォルトです。PKCS#1 パディングには 11 バイトのオーバーヘッドがあります。したがって、暗号文がモジュラスよりも小さい場合、または暗号文が 11 バイトよりも小さい場合、復号化は失敗する必要があります。

于 2015-05-22T12:30:41.230 に答える