0

我收到以下异常:线程“main”中的异常 java.lang.ClassCastException:javax.crypto.CipherInputStream 无法转换为 javax.imageio.stream.ImageOutputStream

我还是想不通。请给我一些建议

// Example code showing how to use Java's Password-Based encryption. This
// example is a simplified form of the code in the documentation for the
// java cryptography architecture.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

public class sample {
   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("rose.jpg");
      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("output.jpg");
     CipherOutputStream cos = new CipherOutputStream(
            output, pbeCipher);
       //File outputFile = new File("image.png");
         ImageIO.write(input,"JPG",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.
   {
      // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      // Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
      // FileInputStream fileinput = new FileInputStream("output.jpg");
      // CipherInputStream cis = new CipherInputStream(fileinput, pbeCipher);
      // BufferedImage input = ImageIO.read(cis);


     File inputFile = new File("output.jpg");
     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));*/
       FileInputStream output = new FileInputStream("output.jpg");
       CipherInputStream cos = new CipherInputStream(
              output, pbeCipher);
        ImageIO.write(input,"JPG",(ImageOutputStream) cos);
        cos.close();

   }
  }
 }
4

2 回答 2

0

在你的倒数第三行你写:

CipherInputStream cos = new CipherInputStream(
          output, pbeCipher);

我认为应该是:

CipherOutputStream cos = new CipherOutputStream(
          output, pbeCipher);
于 2012-05-05T01:27:02.397 回答
0

我认为这是导致问题的代码:

    FileInputStream output = new FileInputStream("output.jpg");
    CipherInputStream cos = new CipherInputStream(
          output, pbeCipher);
    ImageIO.write(input,"JPG",(ImageOutputStream) cos);
    cos.close();

问题很简单。您正在尝试将 InputStream(实际上是 CipherInputStream)转换为 OutputStream 的子类型。那根本行不通。

如果要写入图像,则需要创建输出流链,而不是输入流链。如果您想阅读图像,则不应使用ImageIO.write它来阅读它...

于 2012-05-05T01:28:18.197 回答