java - 尝试解密int时的RSA BadPaddingException

时间:2015-05-22 12:10:27

标签: java encryption int badpaddingexception

我之前已经问过类似的问题,但我无法找到针对我的问题的答案。我正在尝试使用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;
}

1 个答案:

答案 0 :(得分:0)

您需要用于加密图像的方法。它几乎肯定无法按照您目前的预期加密。它可能是普通/原始/教科书/玩具RSA(只是模幂运算)但在这种情况下你需要自己创建解密程序。

每个像素都不可能单独加密。正如JB Nizet已经提到的那样,非常效率低下。 RSA输出是密钥对的大小(其又与模数的字节大小相同)。 RSA密钥对的密钥大小至少应为512位,以使其 hard 解密,并且大约2048位是安全的。通常使用混合方案来使用RSA加密较大的文本(首先使用AES加密,然后使用RSA加密AES密钥)。

此外,您当前正在指定"RSA"作为算法。对于SUNRSA提供商(以及大多数其他提供商),这会转换为"RSA/ECB/PKCS1Padding""ECB""PKCS1Padding"是默认值。 PKCS#1填充的开销为11个字节。因此,如果您的密文小于模数,则密文小于11字节,而解密必须失败 - 并且确实如此。