2016-11-23 3 views
0

Следующая функция используется для дешифрования зашифрованного содержимого, хранящегося в файле. Эта же функция генерирует желаемый результат в версиях ОС Android до Nougat. В Android Nougat дешифрованный файл имеет удвоенный фактический размер по сравнению с файлом, созданным в Andorid M. Также мы обнаружили, что цикл while, используемый для записи данных в файл, выполняется дважды по сравнению с файлом Android M. Пожалуйста, предложите действительное решение.Дешифрование в андроиде N сбой

Уже попытался изменить

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; 

} 

ответ

3

Ну, одна вещь, которая приходит на ум, что вы игнорируете возвращаемое значение cipherInputStream.read(). Вы просто проверяете, читались ли какие-либо данные, но тогда вы пишете весь decodedByteChunk независимо от того, сколько байтов было фактически прочитано. Попробуйте изменить цикл while следующим образом:

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

Посмотрите, исправит ли это вашу проблему.

+0

привет на самом деле исправлена ​​проблема. Но не могли бы вы рассказать об этом. Почему это требовалось для Android-андроида и в старых версиях его работала без этого изменения. С уважением. –

+0

'InputStream.read (byte [] buffer)' не нужно заполнять весь буфер данными. В вашем случае 'decodedByteChunk' имеет длину 1024 байта, что означает, что' cipherInputStream.read (decodedByteChunk) 'может читать 1024 байта ** или меньше **. Он будет читать меньше 1024 байтов, когда вы находитесь в конце потока, и больше нет байтов для чтения или для любой другой внутренней причины, о которой мы ничего не знаем. Старые версии Android, вероятно, читают полные 1024 байта, тогда как в Android N реализация изменилась, и теперь она читает всего 512 байт (или что-то еще). Вы должны всегда проверять, сколько байтов было действительно прочитано. –