加快加密/解密速度?

时间:2011-10-10 13:03:02

标签: android encryption

我有一个加密和解密代码,用于加密和解密视频文件(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);

}

我的问题是如何加快此代码中的解密过程。我试过解密一个10MB的mp4文件,然后在6-7秒内解密。但是,我的目标是< 1秒我想知道的另一件事是,我对FileOutputStream的写入实际上是在减慢进程而不是解密进程本身。关于如何在这里加快速度的任何建议。

我正在使用AES进行加密/解密。

在找到解决方案之前,我将使用ProgressDialog告诉用户等待视频解密(显然,我不会使用“解密”这个词。

5 个答案:

答案 0 :(得分:4)

为什么仅以blockSize增量解密数据?您没有显示对象cipher的类型,但我猜这是一个javax.crypto.Cipher实例。它可以通过任意长度的数组处理update()调用,如果使用更长的数组,您将获得更少的开销。您应该按照8192字节的块处理数据(这是缓冲区的传统长度,它与CPU内部缓存的交互性相当好。)

答案 1 :(得分:1)

bytebiscuit,你的问题给了我过去6天尝试的解决方案。我刚刚修改了你的代码,我的52 mb视频文件在4秒内就被解密了。以前的解密技术需要45秒,这是一个不同的逻辑(不是你的)。这是一个巨大的差异45秒到4秒。我在哪里做了修改我正在修改//修改注释行。我相信如果您的视频是10mb视频,它肯定会在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);

}

答案 2 :(得分:-1)

我建议你使用android sdk中提供的分析工具。它会告诉你你花费最多的时间(即:文件写入或解码)。

请参阅http://developer.android.com/guide/developing/debugging/debugging-tracing.html

这可以在模拟器上以及在实际设备上进行。

答案 3 :(得分:-1)

考虑使用NDK。在Froyo之前的设备上(甚至是Froyo本身),由于缺少JIT(或者在Froyo中非常简单),它会非常慢。即使使用JIT,本机架构优化的加密代码也总是超过Dalvik。

另见this question

顺便说一句,如果您直接使用AES,则可能是doing something wrong。如果这是努力做DRM的一部分,请确保您充分认识到反编译Android应用程序是微不足道的。您的密钥不会是安全的,根据定义,它会使加密失败。

答案 4 :(得分:-1)

您应该考虑使用流式解决方案,而不是花费精力来改进不适当的架构:它有很大的优势来分散解密的计算时间,使其变得不再明显。我的意思是:不要从您的视频源生成另一个文件,而是使用本地http服务器生成流。遗憾的是,SDK中没有这样的组件,您必须自己实现或搜索现有的组件。