2013-08-19 95 views
1

我是新来的android。我正在做一个应用程序,它可以将加密的png图像文件下载到sd卡,然后在解密后显示它。但是我注意到,当解密下载的图像时,我得到“javax.crypto.IllegalBlockSizeException: last block incomplete in decryption image decryption”。然后我发现下载的图像大小为0KB(原始 - 150KB)。然后我从浏览器下载了我的加密图像并进行了检查我得到原始图像大小。我确定我的图片下载课程有问题。但我无法弄清楚。请帮帮我。提前致谢。如何在不丢失数据的情况下下载加密的png文件?

图片下载的AsyncTask类

public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> 
{ 
    private String fileName; 

    @Override 
    protected Bitmap doInBackground(String... urls) 
    { 
     //Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
     return download_Image(urls[0]); 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) 
    { 
     storeImage(result); 

    } 

    private Bitmap download_Image(String url) 
    { 
     Bitmap bm = null; 
     File file = new File(url); 
     fileName = file.getName(); 
     try 
     { 
      URL aURL = new URL(url); 
      URLConnection conn = aURL.openConnection(); 
      conn.connect(); 
      InputStream is = conn.getInputStream(); 
      BufferedInputStream bis = new BufferedInputStream(is); 
      bm = BitmapFactory.decodeStream(bis); 
      bis.close(); 
      is.close(); 
     } 
     catch (OutOfMemoryError e) 
     { 
      Log.e("Hub", "Error getting the image from server : " + e.getMessage().toString()); 
     } 
     catch (IOException e) 
     { 
      Log.e("Hub", "Error getting the image from server : " + e.getMessage().toString()); 
     } 

     return bm; 
    } 

    public void storeImage(Bitmap bm) 
    { 
     BitmapFactory.Options bmOptions; 
     bmOptions = new BitmapFactory.Options(); 
     bmOptions.inSampleSize = 1; 
     String extStorageDirectory = CommonUtils.getDataFromPreferences("metaPath", ""); 

     Log.d("extStorageDirectory", extStorageDirectory); 
     OutputStream outStream = null; 

     File wallpaperDirectory = new File(extStorageDirectory); 
     if (!wallpaperDirectory.exists()) 
     { 
      wallpaperDirectory.mkdirs(); 
     } 
     File outputFile = new File(wallpaperDirectory, fileName); 
     if (!outputFile.exists() || outputFile.length() == 0) 
     { 
      try 
      { 
       outStream = new FileOutputStream(outputFile); 
      } 
      catch (FileNotFoundException e1) 
      { 
       e1.printStackTrace(); 
      } 

      try 
      { 
       bm.compress(Bitmap.CompressFormat.PNG, 100, outStream); 
       outStream.flush(); 
       outStream.close(); 
       Log.d("ScratchActivtiy", "Image Saved"); 

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

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

(所有图片都是我加密的。而且我主持他们的服务器。有一个在ancryption或解密没有问题。我对它们进行测试,所有工作正常。)

CryptClass

public class CryptClass 
{ 

    public byte[] encrypt(String seed, byte[] cleartext) throws Exception 
    { 

     byte[] rawKey = getRawKey(seed.getBytes()); 
     byte[] result = encrypt(rawKey, cleartext); 
     // return toHex(result); 
     return result; 
    } 

    public byte[] decrypt(String seed, byte[] encrypted) throws Exception 
    { 
     byte[] rawKey = getRawKey(seed.getBytes()); 
     byte[] enc = encrypted; 
     byte[] result = decrypt(rawKey, enc); 

     return result; 
    } 

    //done 
    private byte[] getRawKey(byte[] seed) throws Exception 
    { 
     KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
     SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
     sr.setSeed(seed); 
     kgen.init(128, sr); 
     SecretKey skey = kgen.generateKey(); 
     byte[] raw = skey.getEncoded(); 
     return raw; 
    } 

    private byte[] encrypt(byte[] raw, byte[] clear) throws Exception 
    { 
     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
     byte[] encrypted = cipher.doFinal(clear); 
     return encrypted; 
    } 

    private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception 
    { 
     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
     byte[] decrypted = cipher.doFinal(encrypted); 
     return decrypted; 
    } 
} 
+0

我没有看到你张贴的内容加密代码,只需下载图像,并直接传递到'BitmapFactory'运行解密的东西。 – Brigham

+0

是的。我的加密代码工作正常。但是当我从服务器下载该加密图像时,它已经作为SD卡中的0kb png文件下载。下载该图片时发生了一些事情,我无法弄清楚。 – ssdehero

回答

2

如果我理解正确你下载图像第一

BufferedInputStream bis = new BufferedInputStream(is); 
bm = BitmapFactory.decodeStream(bis); 

然后将其保存到与PNG压缩文件:

bm.compress(Bitmap.CompressFormat.PNG, 100, outStream); 

,之后做你解密的文件,对不对?

我想你可能想解密字节,然后将它们保存为png,或者甚至在使用decodeStream之前。否则,您将解密解码流和PNG压缩的加密字节。

尝试跳过所有的BitmapFactory的东西,只是保存原来的文件,然后运行你的解密。在您的AsyncTask:

String saveFilePath = <path to the temporary encrypted file>; 

FileOutputStream outputStream = new FileOutputStream(saveFilePath); 
int bytesRead = -1; 
byte[] buffer = new byte[4096]; 
while ((bytesRead = is.read(buffer)) != -1) { 
    outputStream.write(buffer, 0, bytesRead); 
} 

outputStream.close(); 
inputStream.close(); 

然后在保存的文件

+0

就像这样..我想下载并保存加密格式的文件。后来我解密它。请参阅..我也附加了我的CryptClass。有一个要求,文件甚至不能从文件管理器中看到。 – ssdehero

+1

据我所知,我所说的是你正在下载你的加密文件,然后用PNG压缩保存它,这很可能会改变你的文件内容。然后,您尝试在其上运行解密,这会失败,因为文件字节不再是您的解密能理解的东西。 –

+0

好的。那我该如何解决它。有什么办法以加密格式将其保存在SD卡中? – ssdehero

相关问题