图像文件的加密和解密

结合我的另一个问题 ,并在更改了这部分代码之后

FileOutputStream output = new FileOutputStream("sheepTest.png"); CipherOutputStream cos = new CipherOutputStream(output, pbeCipher); ImageIO.write(input, "PNG", cos); cos.close(); 

从解密部分,我遇到了另一个错误,就是这个

 Exception in thread "main" java.lang.IllegalArgumentException: image == null! at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(Unknown Source) at javax.imageio.ImageIO.getWriter(Unknown Source) at javax.imageio.ImageIO.write(Unknown Source) at encypt.com.trial.main(trial.java:82) 

当我点击sheepTest.png时,文件为空。 错误在哪里? 任何人都可以帮我解决错误吗? 谢谢。

 public class trial { public static void main(String[] arg) throws Exception { // Scanner to read the user's password. The Java cryptography // architecture points out that strong passwords in strings is a // bad idea, but we'll let it go for this assignment. Scanner scanner = new Scanner(System.in); // Arbitrary salt data, used to make guessing attacks against the // password more difficult to pull off. byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 }; { File inputFile = new File("sheep.png"); BufferedImage input = ImageIO.read(inputFile); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); // Get a password from the user. System.out.print("Password: "); System.out.flush(); PBEKeySpec pbeKeySpec = new PBEKeySpec(scanner.nextLine().toCharArray()); // Set up other parameters to be used by the password-based // encryption. PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); // Make a PBE Cyhper object and initialize it to encrypt using // the given password. Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); FileOutputStream output = new FileOutputStream("sheepTest.png"); CipherOutputStream cos = new CipherOutputStream( output, pbeCipher); //File outputFile = new File("image.png"); ImageIO.write(input,"PNG",cos); cos.close(); } // Now, create a Cipher object to decrypt for us. We are repeating // some of the same code here to illustrate how java applications on // two different hosts could set up compatible encryption/decryption // mechanisms. { File inputFile = new File("sheepTest.png"); BufferedImage input = ImageIO.read(inputFile); // Get another (hopefully the same) password from the user. System.out.print("Decryption Password: "); System.out.flush(); PBEKeySpec pbeKeySpec = new PBEKeySpec(scanner.next().toCharArray()); // Set up other parameters to be used by the password-based // encryption. PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20); SecretKeyFactory keyFac = SecretKeyFactory .getInstance("PBEWithMD5AndDES"); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); // Make a PBE Cyper object and initialize it to decrypt using // the given password. Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec); // Decrypt the ciphertext and then print it out. /*byte[] cleartext = pbeCipher.doFinal(ciphertext); System.out.println(new String(cleartext));*/ FileOutputStream output = new FileOutputStream("sheepTest.png"); CipherOutputStream cos = new CipherOutputStream( output, pbeCipher); ImageIO.write(input,"PNG", cos); cos.close(); } } } 

我猜这行是返回null:

 BufferedImage input = ImageIO.read(inputFile); 

ImageIO.read的文档说:

“如果没有注册的ImageReader声称能够读取生成的流,则返回null。”

将null传递给此调用,从而生成NPE:

 ImageIO.write(input,"PNG", cos); 

我不熟悉这个API,但是从文档和我在这里看到的,我想我可以推断出ImageIO.read返回null的原因是因为它试图解释文件中的图像数据,但它可以’因为它是加密的。 在将数据解释为图像之前,您需要先解密数据。

您正在进行解密,但您的格式转换是使用原始的加密文件作为输入,而不是解密的图像数据。

除了NateCK的深刻见解(顺便说一下),我修改了你的解密部分

 // Note that we are not reading the image in here... System.out.print("Decryption Password: "); System.out.flush(); PBEKeySpec pbeKeySpec = new PBEKeySpec(scanner.next().toCharArray()); // Set up other parameters to be used by the password-based // encryption. PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20); SecretKeyFactory keyFac = SecretKeyFactory .getInstance("PBEWithMD5AndDES"); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); // Make a PBE Cyper object and initialize it to decrypt using // the given password. Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec); // We're now going to read the image in, using the cipher // input stream, which wraps a file input stream File inputFile = new File("sheepTest.png"); FileInputStream fis = new FileInputStream(inputFile); CipherInputStream cis = new CipherInputStream(fis, pbeCipher); // We then use all that to read the image BufferedImage input = ImageIO.read(cis); cis.close(); // We then write the dcrypted image out... // Decrypt the ciphertext and then print it out. FileOutputStream output = new FileOutputStream("sheepTest.png"); ImageIO.write(input, "PNG", output); 

我的例子是基于NateCKs的调查结果。 如果你发现它很有用,那么upvote会很好,但是NateCK值得信赖;)