title: Image Encryption & Decryption
body: <p>I want to do encrypt and decrypt on image files. However, when i run this codes, it give me 
  this error </p>
  
  <pre><code>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)
  </code></pre>
  
  <p>and when i tried to open the sheepTest.png image, it cannot be open as the file appears to be damaged, corrupted or it is too large. </p>
  
  <p>I've tried many ways already, however I still cannot find the mistake.Can anyone help me to solve the error?  Thank you. </p>
  
  <pre><code>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();
  
     }
     }
  }
  </code></pre>