AES / CBC加密和解密之间的速度差异?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AES / CBC加密和解密之间的速度差异?相关的知识,希望对你有一定的参考价值。
从理论上讲,我想知道在下列条件下AES / CBC解密与AES / CBC加密相比要慢多少:
- 加密密钥为32字节(256位);
- 块大小为16字节(128位)。
我问的原因是我想知道我所拥有的实现的解密速度是否异常缓慢。我已经对不同大小的随机内存块做了一些测试。结果如下:
64 B:
64KB:
10MB - 520MB:
所有数据都存储在我系统的内部存储器中。应用程序生成要自行加密的数据。在测试PC上禁用虚拟内存,这样就不会有任何I / O调用。
在分析表时,加密和解密之间的区别是否意味着我的实现异常缓慢?我做错了什么吗?
更新:
- 该测试在另一台PC上执行;
- 该测试用随机数据执行;
- Crypto ++用于AES / CBC加密和解密。
解密实现如下:
CryptoPP::AES::Decryption aesDecryption(aesKey, ENCRYPTION_KEY_SIZE_AES);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, aesIv);
CryptoPP::ArraySink * decSink = new CryptoPP::ArraySink(data, dataSizeMax);
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, decSink);
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(ciphertext), cipherSize);
stfDecryptor.MessageEnd();
*dataOutputSize = decSink->TotalPutLength();
更新2:
- 添加了64字节块的结果
作为对称加密,加密和解密应该是fairly close in speed。不确定你的实施,但there are ways to optimize if you're concerned about how the algorithm was used。在实验中,AES is not the fastest and CBC将增加安全性,但会降低安全性。这是一个比较,因为你问的是关键字和块大小:
在分析表时,加密和解密之间的区别是否意味着我的实现异常缓慢?我做错了什么吗?
三四件事情都跳了出来。我有点同意@JamesKPolk - 数字看起来很像。首先,加密库通常用CTR模式标记,而不是CBC模式。另见SUPERCOP benchmarks。任何你必须使用每字节周期数(cpb)来规范机器间的测量单位。在没有上下文的情况下说“9 MB / s”就没有任何意义。
其次,我们需要知道机器及其CPU频率。看起来您正在以9 MB / s的速度推送数据进行加密,并以6.5 MB / s的速度进行解密。像Core-i5 running at 2.7 GHz这样的现代iCore机器将推动CBC模式数据大约为2.5或3.0 cpb,大约为980 MB / s或1 GB / s。甚至我的旧Core2 Duo running at 2.0 GHz移动数据的速度也比你显示的要快。 Core 2以14.5 cpb或130 MB / s的速度移动数据。
第三,废弃此代码。还有很大的改进空间,因此在这方面不值得批评;建议的代码如下。值得一提的是,你创造了许多物品,如ArraySource
和StreamTransformationFilter
。过滤器添加了填充,这会扰乱AES加密和解密基准并使结果发生偏差。您只需要一个加密对象,然后您只需要调用ProcessBlock
或ProcessString
。
CryptoPP::AES::Decryption aesDecryption(aesKey, ENCRYPTION_KEY_SIZE_AES);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, aesIv);
...
第四,Crypto ++ wiki有一个带有以下代码的Benchmarks article。这是一个新的部分,在您提出问题时无法使用。以下是运行测试的方法。
AutoSeededRandomPool prng;
SecByteBlock key(16);
prng.GenerateBlock(key, key.size());
CTR_Mode<AES>::Encryption cipher;
cipher.SetKeyWithIV(key, key.size(), key);
const int BUF_SIZE = RoundUpToMultipleOf(2048U,
dynamic_cast<StreamTransformation&>(cipher).OptimalBlockSize());
AlignedSecByteBlock buf(BUF_SIZE);
prng.GenerateBlock(buf, buf.size());
const double runTimeInSeconds = 3.0;
const double cpuFreq = 2.7 * 1000 * 1000 * 1000;
double elapsedTimeInSeconds;
unsigned long i=0, blocks=1;
ThreadUserTimer timer;
timer.StartTimer();
do
{
blocks *= 2;
for (; i<blocks; i++)
cipher.ProcessString(buf, BUF_SIZE);
elapsedTimeInSeconds = timer.ElapsedTimeAsDouble();
}
while (elapsedTimeInSeconds < runTimeInSeconds);
const double bytes = static_cast<double>(BUF_SIZE) * blocks;
const double ghz = cpuFreq / 1000 / 1000 / 1000;
const double mbs = bytes / 1024 / 1024 / elapsedTimeInSeconds;
const double cpb = elapsedTimeInSeconds * cpuFreq / bytes;
std::cout << cipher.AlgorithmName() << " benchmarks..." << std::endl;
std::cout << " " << ghz << " GHz cpu frequency" << std::endl;
std::cout << " " << cpb << " cycles per byte (cpb)" << std::endl;
std::cout << " " << mbs << " MiB per second (MiB)" << std::endl;
在2.7 GHz的Core-i5 6400上运行代码会导致:
$ ./bench.exe
AES/CTR benchmarks...
2.7 GHz cpu frequency
0.58228 cycles per byte (cpb)
4422.13 MiB per second (MiB)
第五,当我修改上面显示的基准程序来操作64字节块时:
const int BUF_SIZE = 64;
unsigned int blocks = 0;
...
do
{
blocks++;
cipher.ProcessString(buf, BUF_SIZE);
elapsedTimeInSeconds = timer.ElapsedTimeAsDouble();
}
while (elapsedTimeInSeconds < runTimeInSeconds);
对于64字节块,我认为Core-i5 6400在2.7 GHz时为3.4 cpb或760 MB / s。该库对小缓冲区有效,但大多数(全部?)库都有。
$ ./bench.exe
AES/CTR benchmarks...
2.7 GHz cpu frequency
3.39823 cycles per byte (cpb)
757.723 MiB per second (MiB)
第六,您需要让处理器退出节能模式或低能耗状态,以获得最佳/最一致的结果。该库使用governor.sh
在Linux上执行此操作。它可以在TestScript/
目录中找到。
第七,当我切换到CTR模式解密时:
CTR_Mode<AES>::Decryption cipher;
cipher.SetKeyWithIV(key, key.size(), key);
然后我看到批量解密的速率相同:
$ ./bench.exe
AES/CTR benchmarks...
2.7 GHz cpu frequency
0.579923 cycles per byte (cpb)
4440.11 MiB per second (MiB)
第八,这是一堆不同机器上的基准数字集合。在调整测试时,它应该提供一个粗略的目标。
我的Beaglebone开发板以980 MHz的频率运行,其数据速率是您报告的两倍。 Beaglebone以20 MB / s的速度实现了40 cpb的无聊,因为它是星际C / C ++;并没有针对A-32进行优化。
- Skylake Core-i5 @ 2.7 GHz https://www.cryptopp.com/benchmarks.html
- Core2 Duo @ 2.0 GHz https://www.cryptopp.com/benchmarks-core2.html
- LeMaker HiKey Church SoC Aarch64 @ 1.2 GHz https://www.cryptopp.com/benchmarks-hikey.html
- AMD Opteron Aarch64 @ 2.0 GHz https://www.cryptopp.com/benchmarks-opteron.html
- BananaPi Cortex-A7开发板@ 860MHz https://www.cryptopp.com/benchmarks-bananapi.html
- IBM Power8 Server @ 4.1 GHz https://www.cryptopp.com/benchmarks-power8.html
我的要点是:
- CTR模式批量加密和解密在现代机器上大致相同
- 点击率模式键设置不一样,解密在现代机器上需要更长的时间
- 小块尺寸比大块尺寸更昂贵
这是我期待看到的一切。
我认为你的下一步是在Crypto ++ wiki上使用the sample program收集一些数据,然后评估结果。
从理论上讲,AES解密速度要慢30%。这是Rijndael系统的一般属性。
资料来源:http://www4.ncsu.edu/~hartwig/Teaching/437/aes.pdf
以上是关于AES / CBC加密和解密之间的速度差异?的主要内容,如果未能解决你的问题,请参考以下文章
QT:AES-256-CBC 根据 PHP 代码在 C++ 中加密/解密
AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) 使用 openssl C 加密/解密
尝试使用 BouncyCastle 的 AES-CBC 来解密加密文本的问题