androidN 解密失败

Decryption in android N fails

以下函数用于解密存储在文件中的加密内容。相同的函数在 Android OS 版本中生成所需的输出,直到 Nougat。在 Android Nougat 中,与 Andorid M 中生成的文件相比,解密文件的实际大小是实际大小的两倍。我们还发现,用于将数据写入文件的 while 循环执行次数是比较时的两倍到 Android M 的那个。请提出一个有效的解决方案。

已经尝试更改

byte[] keyBytes = key.getBytes();
byte[] ivBytes = ivString.getBytes(); 

byte[] keyBytes = key.getBytes("UTF-8");
byte[] ivBytes = ivString.getBytes("UTF-8");


public static  void  decryptPDFBook(String filePath, String key, String ivString, ShelfItem item) {

    InputStream  finStream;
    byte[] keyBytes = key.getBytes();
    byte[] ivBytes = ivString.getBytes();

    SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivParamSpec = new IvParameterSpec(ivBytes);
    try {
        finStream = new FileInputStream(new File(filePath));
        Cipher cipherInstance = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipherInstance.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParamSpec);
        CipherInputStream cipherInputStream = new CipherInputStream(finStream, cipherInstance);
        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();

        String newpath= Environment.getExternalStorageDirectory() +File.separator+ "ebooks"+File.separator+"ief"+File.separator+item.getId()+"_temp.pdf";

        File dir = new File(Environment.getExternalStorageDirectory() +File.separator+ "ebooks"+File.separator+"ief");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(newpath);

        byte[] decodedByteChunk = new byte[1024];   
        int bytesAvailable = cipherInputStream.read(decodedByteChunk);
        while (bytesAvailable != -1) {
            fos.write(decodedByteChunk);
            bytesAvailable = cipherInputStream.read(decodedByteChunk);
        }
        byteArrayOS.close();
        cipherInputStream.close();
        fos.close();

       File encryptedFile = new File(filePath);
        if(encryptedFile.exists()){
           encryptedFile.delete();
           File file = new File (newpath);
           file.renameTo(encryptedFile);
       }


    } catch (NoSuchPaddingException nspe) {
        System.out.println("Inside NoSuchPaddingException");
        //Log.d("ELSAPAC", "BookExtractionUtil decryptPDFBook NoSuchPaddingException");
        nspe.printStackTrace();
    } catch (NoSuchAlgorithmException nsae) {
        System.out.println("Inside NoSuchAlgorithmException");
        //Log.d("ELSAPAC", "BookExtractionUtil decryptPDFBook NoSuchAlgorithmException");
        nsae.printStackTrace();
    } catch (InvalidKeyException ike) {
        System.out.println("Inside InvalidKeyException");
        //Log.d("ELSAPAC", "BookExtractionUtil decryptPDFBook InvalidKeyException");
        ike.printStackTrace();
    } catch (InvalidAlgorithmParameterException iape) {
        System.out.println("Inside InvalidAlgorithmParameterException");
        //Log.d("ELSAPAC", "BookExtractionUtil decryptPDFBook InvalidAlgorithmParameterException");
        iape.printStackTrace();
    } catch (IOException ioe) {     
        System.out.println("Inside IOException");
        //Log.d("ELSAPAC", "BookExtractionUtil decryptPDFBook IOException");
        ioe.printStackTrace();
        decryptPDFWithoutPadding( filePath,key,ivString,item);//pad block corrupted
        //return data;
    } catch (Exception e) {
       e.printStackTrace();
    }
     finally {        
    }

   // return null;

}

好吧,我想到的一件事是您忽略了 cipherInputStream.read() 的 return 值。您只是检查是否读取了任何数据,但是无论实际读取了多少字节,您都写入了整个 decodedByteChunk 。尝试像这样修改您的 while 循环:

int bytesAvailable = cipherInputStream.read(decodedByteChunk);
while (bytesAvailable != -1) {
    fos.write(decodedByteChunk, 0, bytesAvailable);
    bytesAvailable = cipherInputStream.read(decodedByteChunk);
}

看看是否能解决您的问题。