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的速度移动数据。

第三,废弃此代码。还有很大的改进空间,因此在这方面不值得批评;建议的代码如下。值得一提的是,你创造了许多物品,如ArraySourceStreamTransformationFilter。过滤器添加了填充,这会扰乱AES加密和解密基准并使结果发生偏差。您只需要一个加密对象,然后您只需要调用ProcessBlockProcessString

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进行优化。


我的要点是:

  • CTR模式批量加密和解密在现代机器上大致相同
  • 点击率模式键设置不一样,解密在现代机器上需要更长的时间
  • 小块尺寸比大块尺寸更昂贵

这是我期待看到的一切。

我认为你的下一步是在Crypto ++ wiki上使用the sample program收集一些数据,然后评估结果。

另一答案

从理论上讲,AES解密速度要慢30%。这是Rijndael系统的一般属性。

资料来源:http://www4.ncsu.edu/~hartwig/Teaching/437/aes.pdf

以上是关于AES / CBC加密和解密之间的速度差异?的主要内容,如果未能解决你的问题,请参考以下文章

小程序:JS AES加密解密(ECB/CBC)

QT:AES-256-CBC 根据 PHP 代码在 C++ 中加密/解密

AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) 使用 openssl C 加密/解密

尝试使用 BouncyCastle 的 AES-CBC 来解密加密文本的问题

AES在线加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各种加密解密源码

CryptoJS<AES-CBC加密和解密>