【问题标题】:Java's CipherOutputStream vs. Apache's CryptoOutputStream performanceJava 的 CipherOutputStream 与 A​​pache 的 CryptoOutputStream 性能对比
【发布时间】:2018-12-21 17:38:31
【问题描述】:

我在我的应用程序中实现 AES256 加密,它是通过自定义 FilterOutputStream 完成的,我将提供的输出流与加密流包装在一起。目标加密是AES/CTR/NoPadding

起初,我开始使用标准 Java 的 javax.crypto.CipherOutputStream,所以代码看起来像这样:

...
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, sessionKey, new IvParameterSpec(ivBytes));
this.out = new CipherOutputStream(out, cipher);

但我注意到使用这种方法加密 100 MB 文件需要大约 10 分钟(是的,分钟!),这显然不适合吞吐量。

所以我开始修补,我的第一个猜测是使用 Bouncy Castle 作为Cipher 提供程序(因为它被推荐在这里的某个地方,在 SO)。于是代码变成了:

...
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding", BouncyCastleProvider.PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, sessionKey, new IvParameterSpec(ivBytes));
this.out = new CipherOutputStream(out, cipher);

随着这种变化,加密时间减少到约 45 秒,比之前好 10 倍多,但仍然不合适。

所以我接下来要做的是用 Apache Commons Crypto 提供的 CryptoOutputStream 替换标准的 CipherOutputStream,所以代码开始看起来像这样:

...
this.out = new CryptoOutputStream("AES/CTR/NoPadding", new Properties(), out, sessionKey, new IvParameterSpec(ivBytes));

而且 - 瞧 - 同一个文件的加密现在只需约 2 秒,因此它比 BC 的方法快 15 倍,比原始方法快 150 倍以上!

所以,我的问题是……这背后的原因是什么?这仅仅是Java中默认的CipherOutputStream如此糟糕而Apache的CryptoOutputStream如此优秀的事实吗?但是,Bouncy Castle 如何提升标准CipherOutputStream?我在这里错过了什么?

UPD:我相信它不是 Java I/O classes and performance 的重复,因为那个问题明确是关于普通流的性能,但这个问题是关于加密流的性能,答案并不那么明显。

【问题讨论】:

  • 您是否在任何地方使用缓冲流?如果不考虑先尝试。
  • 什么意思?这是一个FilterOutputStream,它包装了任意外部OutputStream(在我的例子中是FileOutputStream)。所以我不手动创建任何流 - 我将 FileOutputStream 包装到 CipherOutputStreamCryptoOutputStream
  • 缓冲流确实可以为加密流创造奇迹——无论如何.. Apache 的 CipherOutputStream 使用 OPENSSL,可以利用硬件中的加密指令.. 参见 this
  • @MarkRotteveel,实际上,你是对的:如果我将OutputStream 包装成BufferedOutputStream,然后再包装成CipherOutputStream,它的运行速度几乎与CryptoOutputStream 一样快。如果您将其发布为答案,我会接受。

标签: java apache encryption aes bouncycastle


【解决方案1】:

您需要将流包装在 BufferedOutputStream 中,这可以提高 IO 效率,因为使用单个较大的写入而不是许多小写入。

根据具体用途,缓冲CipherOutputStream 可能比out 更好。有时将两者都包装起来可能会有所帮助。 YMMV,我建议测试最有效的方法。

【讨论】:

    猜你喜欢
    • 2022-12-10
    • 1970-01-01
    • 2017-10-12
    • 2011-08-23
    • 1970-01-01
    • 2018-03-14
    • 2013-01-16
    • 2012-03-06
    相关资源
    最近更新 更多