2012-08-26 85 views
0

我想對圖像文件進行加密和解密。然而,當我運行這個代碼,它給我 這個錯誤圖像加密和解密

Exception in thread "main" java.lang.ClassCastException: javax.crypto.CipherInputStream cannot be cast to javax.imageio.stream.ImageOutputStream 
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));*/ 
     FileInputStream output = new FileInputStream("sheepTest.png"); 
     CipherInputStream cos = new CipherInputStream(
       output, pbeCipher); 
     ImageIO.write(input,"PNG",(ImageOutputStream) cos); 
     cos.close(); 

    } 
    } 
} 
+0

你真的需要了解**輸入**和**輸出**的區別。就像在你的新問題中一樣,你在這裏糟糕地混合起來。 –

+0

@Twister是否可以安全使用超過2或3張圖像加密的方法? – Erum

回答

0

首先,不要命名您的FileInputStream輸出。其次,問題是,你嘗試你CipherInputStream轉換爲一個ImageOutputStream(如錯誤說)位置:

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

這不會因爲CipherInputStream工作是不是一個ImageOutputStream。


好吧,發現你的命名有進一步的問題;我認爲你的名字是正確的,但是使用了錯誤的類;改變你的最後幾行這樣的:

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

對於寫,要使用一個OutputStream(或FileOutputStream中或密碼或任何你需要的)。

+0

不要把我的FileInputStream輸出?含義?當我刪除'(ImageOutputStream)'時寫入時出錯。它說'類型ImageIO中寫入方法(RenderedImage,String,ImageOutputStream)不適用於參數(BufferedImage,String,CipherInputStream)' – Twister

+0

不要將您的FileInputStream輸出命名*只是命名約定,請參閱第二部分問題稍有不同 –

+0

再次看到第二部分;你不希望他們都是輸入,使所有輸出,FileOutputStream,而不是輸入 –