2013-01-17 32 views
1

这里是我的简单的图像加密类,其中我:无法解密和读取加密图像文件

  1. 读一个图像从一个地方到字节
  2. 加密这些字节
  3. 再次创建图像从这些加密的字节

代码:

public class ImageEncrypt { 

    Cipher cipher; 

    public static byte[] convertImageToByteArray(String sourcePath) { 
    byte[] imageInByte = null; 
    try{ 

     BufferedImage originalImage = ImageIO.read(new File(
     sourcePath)); 

     // convert BufferedImage to byte array 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     ImageIO.write(originalImage, "jpg", baos); 
     baos.flush(); 
     imageInByte = baos.toByteArray(); 
     baos.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
    return imageInByte; 
    } 

    public static void convertByteArrayToImage(byte[] b , String path) { 

    try{ 

     InputStream in = new ByteArrayInputStream(b); 
     BufferedImage bImageFromConvert = ImageIO.read(in); 

     ImageIO.write(bImageFromConvert, "jpg", new File(
     path)); 

    }catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
    } 


    public static void main(String args []){ 
    final String strPassword = "password12345678"; 

    SecretKeySpec initVector = new SecretKeySpec(strPassword.getBytes(), "AES"); 
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(strPassword.getBytes()); 

    try{ 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

     cipher.init(Cipher.ENCRYPT_MODE, initVector, paramSpec); 

     byte[] ecrypted = cipher.doFinal(convertImageToByteArray("C:/Users/user/Desktop/a.jpg")); 

     convertByteArrayToImage(ecrypted,"C:/Users/user/user/enc.jpg"); 

     System.out.println("converted to encrypted file .... "); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
    } 

现在,当我尝试从加密字节创建映像时,我在第三步中遇到了问题。它会抛出一个例外如下:

java.lang.IllegalArgumentException: image == null! 
    at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925) 
    at javax.imageio.ImageIO.getWriter(ImageIO.java:1591) 
    at javax.imageio.ImageIO.write(ImageIO.java:1520) 
    at ImageEncrypt.convertByteArrayToImage(ImageEncrypt.java:55) 
    at ImageEncrypt.main(ImageEncrypt.java:83) 

我不知道我要去哪里错了?我正在做相同的转换文件(文档,PDF等)加密,它工作正常(当然在这种情况下,我使用不同的流类进行字节转换),但我无法理解为什么它在这里搞乱?

回答

2

加密数据后,它不再是有效的图像文件。试图在加密数据上使用ImageIO就像打开加密记事本中文本文件的结果,并希望看到文本。

要获取Image,您需要先解密数据,然后再请ImageIO来读取它。

你很难完全清楚你的convertByteArrayToImage方法的真正目的 - 如果目标只是将字节写入文件,为什么要通过Image呢?为什么不直接将字节转储到磁盘?他们已经图像的加密表示 - 没有必要再尝试将它们解释为图像。如果您想要应用某种图像转换(例如,即使输入是PNG,总是写出一个JPEG,),那么应该在未加密的数据上完成该操作。

(同样地,对convertImageToByteArray,因为你开始与磁盘上的文件,有一个在装载,作为一个图像,除非你想要执行的特定影像变换没有意义的。)

副作用注意事项:

  • 不要使用String.getBytes()超载不接受一个字符集 - 它将使用平台默认的编码,这意味着它不是跨平台移植
  • 你将加密的数据T base64也是如此,但是忽略了结果。为什么?
+0

base64行只是错误地打印 – Despicable

+0

'为什么不把字节直接转储到磁盘?'我倾倒他们的形式image.Please清楚你想说什么?我没有得到它 – Despicable

+1

@despicable:当它到达磁盘时,*它只是字节*。它不像文件“知道”它是一个图像,只是因为它是由'ImageIO'编写的。换句话说:加密不关心数据的性质。您可以在不知道数据通常如何解释的情况下加密文件:加载字节,加密它们,保存结果。这里根本不需要'ImageIO'。 –