2015-04-15 52 views
1

直到kitkat,加密/解密工作正常,但在棒棒糖中它只解密部分數據。使用AES的Android Lollipop解密無法正常工作

我沒有加密的問題,因爲我用棒棒糖加密了一個文件,並用kitkat將它解密,但它的工作正常,但反之亦然。

這是代碼。

加密代碼

Encrypt(BufferedInputStream is, File destfile, String passcode) { 
     bis = is; 
     try { 
      fos = new FileOutputStream(destfile); 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     dest = new BufferedOutputStream(fos, 1024); 
     this.passcode = passcode; 
    } 

    static void encrypt() throws IOException, NoSuchAlgorithmException, 
    NoSuchPaddingException, InvalidKeyException { 

     // Length is 16 byte 
     SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES"); 

     // Create cipher 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, sks); 
     // Wrap the output stream 
     CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
     // Write bytes 
     int b; 
     byte[] d = new byte[1024]; 
     while ((b = bis.read(d)) != -1) { 
      cos.write(d, 0, b); 
     } 
     // Flush and close streams. 
     cos.flush(); 
     cos.close(); 
     bis.close(); 
    } 

解密代碼

public Decrypt(String path, String pathcode) { 
     // TODO Auto-generated constructor stub 
     filepath = path; 
     try { 
      fis = new FileInputStream(new File(path)); 
      this.passcode = pathcode; 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    static String decrypt() throws IOException, NoSuchAlgorithmException, 
    NoSuchPaddingException, InvalidKeyException { 

     SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.DECRYPT_MODE, sks); 
     CipherInputStream cis = new CipherInputStream(fis, cipher); 
     int size = fis.available(); 
     byte[] resdata = new byte[size]; 
     cis.read(resdata, 0, size); 
     String newres = new String(resdata, "UTF-8").trim(); 
     //write("decrypted_file.xhtml",newres); 
     if(fis!=null) 
     { 
     fis.close(); 
     } 
     if(cis!=null) 
      cis.close(); 
     return newres; 
    } 

是什麼在此代碼的問題?我需要做更多的事嗎?

回答

2

available()不一定會返回整個流的長度,只是估計的可以無阻塞地讀取的字節數。因此,使用ByteArrayOutputStream來存儲字節,然後轉換爲字節數組:

CipherInputStream cis = new CipherInputStream(fis, cipher); 
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
int bytesRead; 
byte[] data = new byte[1024]; 
while ((bytesRead = cis.read(data, 0, data.length)) != -1) { 
    buffer.write(data, 0, bytesRead); 
} 
buffer.flush(); 
byte[] resdata = buffer.toByteArray(); 
String newres = new String(resdata, "UTF-8").trim(); 
+0

它的工作!偉大的:-)。非常感謝你。但是爲什麼可用()在棒棒糖之前工作,而不是在棒棒糖中工作。 – kartiraman

+0

不客氣。我不知道爲什麼available()停止在Lollipop中工作,但我的猜測是Google改變了內部緩衝在CipherInputStream中的工作方式,或者可能他們甚至沒有在Lollipop之前使用緩衝,所以之前可用的字節總是相等的到文件/流的總長度。 – samgak