Ускорить шифрование / дешифрование? - PullRequest
3 голосов
/ 10 октября 2011

У меня есть код шифрования и дешифрования, который я использую для шифрования и дешифрования видеофайлов (mp4). Я пытаюсь ускорить процесс расшифровки, так как шифрование не очень актуально для моего случая. Вот код, который у меня есть для процесса расшифровки:

private static void  decryptFile() throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException
    {

        //int blockSize = cipher.getBlockSize();
        int blockSize = cipher.getBlockSize();
        int outputSize = cipher.getOutputSize(blockSize);
        System.out.println("outputsize: " + outputSize);
        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];
        in= new FileInputStream(inputFile);
        out=new FileOutputStream(outputFile);

        BufferedInputStream inStream = new BufferedInputStream(in);
        int inLength = 0;;
        boolean more = true;
        while (more)
          {
             inLength = inStream.read(inBytes);
             if (inLength == blockSize)
             {
                int outLength 
                   = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);

             }
             else more = false;         
          }
          if (inLength > 0)
             outBytes = cipher.doFinal(inBytes, 0, inLength);
          else
             outBytes = cipher.doFinal();

          out.write(outBytes);

}

Мой вопрос заключается в том, как ускорить процесс расшифровки в этом коде. Я попытался расшифровать MP4-файл размером 10 МБ, и он расшифровывается за 6-7 секунд. Тем не менее, я стремлюсь <1 секунды. Еще одна вещь, которую я хотел бы знать, заключается в том, что моя запись в FileOutputStream действительно замедляет процесс, а не сам процесс расшифровки. Любые предложения о том, как ускорить процесс здесь. </p>

Я использую AES для шифрования / дешифрования.

Пока я не найду решение, я буду использовать ProgressDialog, который скажет пользователю подождать, пока видео не будет расшифровано (очевидно, я не буду использовать слово: расшифровано).

Ответы [ 5 ]

4 голосов
/ 10 октября 2011

Почему вы расшифровываете данные только с шагом blockSize?Вы не показываете тип объекта cipher, но я предполагаю, что это экземпляр javax.crypto.Cipher.Он может обрабатывать update() вызовы для массивов произвольной длины, и вы будете иметь гораздо меньше накладных расходов, если будете использовать более длинные массивы.Вы должны обрабатывать данные, скажем, блоками, скажем, 8192 байта (это традиционная длина буфера, она достаточно хорошо взаимодействует с внутренними кешами ЦП).

1 голос
/ 16 октября 2015

bytebiscuit, ваш вопрос дал мне решение, которое я пробовал за последние 6 дней.Я только немного изменил ваш код, и мой видеофайл размером 52 МБ расшифровывается всего за 4 секунды.Предыдущая техника расшифровки заняла 45 секунд, что было другой логикой (не вашей).Это огромная разница от 45 до 4 секунд.Где бы я ни делал модификацию, я помещаю // измененные строки комментариев.Я уверен, что если ваше видео 10 МБ, оно наверняка расшифруется за 1 секунду.Попробуйте применить это, должно получиться.

private static void  decryptFile() throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException
    {

        //int blockSize = cipher.getBlockSize();
        int blockSize = cipher.getBlockSize();
        int outputSize = cipher.getOutputSize(blockSize);
        System.out.println("outputsize: " + outputSize);
        byte[] inBytes = new byte[blockSize*1024]; //modified
        byte[] outBytes = new byte[outputSize * 1024]; //modified
        in= new FileInputStream(inputFile);
        out=new FileOutputStream(outputFile);

        BufferedInputStream inStream = new BufferedInputStream(in);
        int inLength = 0;;
        boolean more = true;
        while (more)
          {
             inLength = inStream.read(inBytes);
             if (inLength/1024 == blockSize) //modified
             {
                int outLength 
                   = cipher.update(inBytes, 0, blockSize*1024, outBytes);//modified
                out.write(outBytes, 0, outLength);

             }
             else more = false;         
          }
          if (inLength > 0)
             outBytes = cipher.doFinal(inBytes, 0, inLength);
          else
             outBytes = cipher.doFinal();

          out.write(outBytes);

}
0 голосов
/ 31 марта 2013

Вместо того, чтобы тратить усилия на улучшение неадекватной архитектуры, вы должны рассмотреть потоковое решение: оно имеет большое преимущество в том, чтобы распределить время вычислений для дешифрования, чтобы оно не стало более заметным. Я имею в виду: не создавайте другой файл из вашего источника видео, а скорее поток с локальным http-сервером. К сожалению, в SDK такого компонента нет, вам нужно создать собственную реализацию или найти существующую.

0 голосов
/ 10 октября 2011

Рассмотрите возможность использования NDK.На устройствах, предшествующих Froyo (и даже самому Froyo), он будет очень медленным из-за отсутствия JIT (или очень простого в Froyo).Даже с JIT криптографический код с оптимизированной архитектурой всегда будет опережать Dalvik.

См. Также этот вопрос .

Кроме того, если вы используете AES напрямую, вы, вероятно, делаете что-то неправильно .Если это является частью усилий по созданию DRM, убедитесь, что вы полностью понимаете тот факт, что декомпиляция приложения для Android тривиальна.Ваш ключ не будет защищенным, что по определению нарушает шифрование.

0 голосов
/ 10 октября 2011

Я предлагаю вам использовать инструмент профилирования, предоставляемый в Android SDK.он скажет вам, где вы проводите больше всего времени (например, запись или декодирование файла).

см. http://developer.android.com/guide/developing/debugging/debugging-tracing.html

Эта работа работает как на эмуляторе, так и на реальном устройстве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...