0

I know similar questions have been asked before, but I can't find an answer specific to my problem. I am trying to use RSA encryption to take an image with encrypted pixels and decrypt it using the same private key. I keep on running into a problem though when I try to decrypt the int I get from the pixels of the image using getRGB(). Here is my Code:

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);

This is in my main class which calls method RSADecryptB from another class, here is that method:

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;

}

When I run the program the output is this:

-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)

I don't understand why this is going on. -1606258341 is the value of the pixel, the output of 5 and 4 are because of the NoSuchPaddingException and the BadPaddingException. If anyone can help explain why this is happening and what I'm doing wrong that would be great. Thanks!

Edit: I know I probably shouldn't be using RSA directly, but I am also doing the encryption myself, pixel by pixel. I'm doing this more to practice using bufferedimages/ byte arrays / rsa rather than to create the most efficient/secure program. Also, when I decrypt the integer in my encryption method it works fine. Its when I decrypt it from a different method that I get the error. Also, after encrypting the image is saved to a file, then extracted to decrypt. Here is my Encryption method also (it doesn't use any padding):

 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);

}

  } 

Then here's the RSAEncrypt method:

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 提供者(以及大多数其他提供者) ,这转换为"RSA/ECB/PKCS1Padding"默认值。PKCS#1 填充有 11 个字节的开销。因此,如果您的密文小于模数密文小于 11 个字节,则解密必须失败 - 确实如此。"ECB""PKCS1Padding"

于 2015-05-22T12:30:41.230 回答