理论上,我想知道在下列条件下,AES / CBC解密与AES / CBC加密相比要慢得多:
我问的原因是我想知道我所拥有的实现的解密速度是否异常缓慢。我已经对不同大小的随机内存块做了一些测试。结果如下:
64B:
64KB:
10MB - 520MB:
所有数据都存储在我系统的内部存储器中。应用程序生成要自行加密的数据。在测试PC上禁用虚拟内存,这样就不会有任何I / O调用。
分析表时,加密和解密之间的区别是否意味着我的实现异常缓慢?我做错了什么?
更新
解密实现如下:
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:
答案 0 :(得分:2)
作为对称加密,加密和解密应为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会增加安全性,但会降低安全性。这是一个比较,因为你问的是密钥和块大小:
答案 1 :(得分:1)
分析表时,加密和解密之间的区别是否意味着我的实现异常缓慢?我做错了什么?
三四件事突然袭来。我有点同意@JamesKPolk - 数字看起来很像。首先,加密库通常用CTR模式标记,而不是CBC模式。另请参阅SUPERCOP benchmarks。任何你必须使用每字节周期数(cpb)来规范机器间的测量单位。在没有上下文的情况下说“9 MB / s”就没有任何意义。
其次,我们需要了解机器及其CPU频率。看起来您正在以9 MB / s的速度推送数据进行加密,并以6.5 MB / s的速度进行解密。现代iCore机器,如Core-i5 running at 2.7 GHz,将推动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字节块的2.7 GHz,Core-i5 6400我看到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)
Eigth,这是一系列不同机器上的基准数字集合。在调整测试时,它应该提供一个粗略的目标。
我的Beaglebone开发板运行速度为980 MHz,速度是您报告速度的两倍。 Beaglebone以20 MB / s的速度实现了40 cpb的无聊,因为它是星际C / C ++;而且没有针对A-32进行优化。
Skylake Core-i5 @ 2.7 GHz
Core2 Duo @ 2.0 GHz
LeMaker HiKey Kirik SoC Aarch64 @ 1.2 GHz
AMD Opteron Aarch64 @ 2.0 GHz
BananaPi Cortex-A7开发板@ 860MHz
IBM Power8 Server @ 4.1 GHz
我的要点是:
这是我期待看到的一切。
我认为您的下一步是使用Crypto ++ wiki上的the sample program收集一些数据,然后评估结果。
答案 2 :(得分:-2)
理论上,AES解密速度慢30%。这是Rijndael系统的一般属性。