我做了一个小型测试基准,比较了 .NET 的System.Security.Cryptography
AES 实现与 BouncyCastle.Org 的 AES。
GitHub 代码链接:https ://github.com/sidshetye/BouncyBench
我对 AES-GCM 特别感兴趣,因为它是一种“更好”的加密算法,而 .NET 缺少它。我注意到,虽然 .NET 和 BouncyCastle 之间的 AES 实现非常相似,但 GCM 性能却很差(有关更多信息,请参阅下面的额外背景)。我怀疑这是由于许多缓冲区副本或其他原因。为了更深入地了解,我尝试分析代码(VS2012 =>Analyze
菜单栏选项 => Launch performance wizard
)并注意到 mscorlib.dll 中有很多 CPU 烧伤
问题:在这种情况下,我如何才能弄清楚是什么占用了大部分 CPU?现在我所知道的是“Init() 中的某些行/调用会在 mscorlib.ni.dll 中消耗 47% 的 CPU” - 但不知道具体的行,我不知道在哪里(尝试和)优化。有什么线索吗?
额外背景:
基于David A. McGrew的“ The Galois/Counter Mode of Operation (GCM) ”论文,我阅读了“二进制字段中的乘法可以使用各种时间-内存权衡。它可以在不依赖键的内存的情况下实现,在这种情况下,它的运行速度通常比 AES 慢几倍。愿意牺牲适度内存的实现可以轻松实现比 AES 更高的速度。
如果你看一下结果,基本的 AES-CBC 引擎性能是非常可比的。AES-GCM 添加 GCM 并在 CTR 模式下重用其下方的 AES 引擎(比 CBC 更快)。但是,GCM 除了 CTR 模式外,还在 GF(2^128) 字段中添加了乘法,因此可能存在其他减速区域。无论如何,这就是我尝试分析代码的原因。
对于感兴趣的人,我的快速测试性能基准在哪里。它位于 Windows 8 VM 和 YMMV 中。该测试是可配置的,但目前它是在加密数据库的许多单元格时模拟加密开销(=> 许多但很小的明文输入)
Creating initial random bytes ...
Benchmark test is : Encrypt=>Decrypt 10 bytes 100 times
Name time (ms) plain(bytes) encypted(bytes) byte overhead
.NET ciphers
AES128 1.5969 10 32 220 %
AES256 1.4131 10 32 220 %
AES128-HMACSHA256 2.5834 10 64 540 %
AES256-HMACSHA256 2.6029 10 64 540 %
BouncyCastle Ciphers
AES128/CBC 1.3691 10 32 220 %
AES256/CBC 1.5798 10 32 220 %
AES128-GCM 26.5225 10 42 320 %
AES256-GCM 26.3741 10 42 320 %
R - Rerun tests
C - Change size(10) and iterations(100)
Q - Quit