2013-08-19 137 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

相關問題