C++ AES CTR模式-加密\加密解密+;-我做得对吗?

C++ AES CTR模式-加密\加密解密+;-我做得对吗?,c++,cryptography,aes,crypto++,C++,Cryptography,Aes,Crypto++,在我的应用程序中,我需要使用加密算法,该算法允许我在加密缓冲区中按请求的偏移量解密单个字节,而无需读取周围的块。我的选择是AES和CTR模式,使用Crypto++库。因为找不到好的例子,我自己写了: unique_ptr<vector<byte>> GetIV(int counter) { byte* counterPtr = (byte*)&counter; unique_ptr<vector<byte>> iv(new

在我的应用程序中,我需要使用加密算法,该算法允许我在加密缓冲区中按请求的偏移量解密单个字节,而无需读取周围的块。我的选择是AES和CTR模式,使用Crypto++库。因为找不到好的例子,我自己写了:

unique_ptr<vector<byte>> GetIV(int counter)
{
    byte* counterPtr = (byte*)&counter;
    unique_ptr<vector<byte>> iv(new vector<byte>());
    for (int j = 0; j < 4; j++)
    {
        iv->push_back(counterPtr[j]);
    }
    return move(iv);
}

unique_ptr<vector<uint8_t>> Encrypt(const vector<uint8_t>& plainInput)
{
    unique_ptr<vector<uint8_t>> encryptedOutput(new vector<uint8_t>(plainInput.size()));

    for (int i = 0; i < plainInput.size(); i++)
    {
        auto iv = GetIV(i);
        CTR_Mode<AES>::Encryption encryptor(_key->data(), _key->size(), iv->data());
        byte encryptedValue = encryptor.ProcessByte(plainInput.at(i));
        encryptedOutput->at(i) = encryptedValue;
    }

    return move(encryptedOutput);
}

unique_ptr<vector<uint8_t>> Decrypt(const vector<uint8_t>& encryptedInput, int position)
{
    unique_ptr<vector<uint8_t>> decryptedOutput(new vector<uint8_t>(encryptedInput.size()));

    for (int i = 0; i < encryptedInput.size(); i++)
    {
        auto iv = GetIV(position + i);
        CTR_Mode<AES>::Decryption decryptor(_key->data(), _key->size(), iv->data());
        byte decryptedValue = decryptor.ProcessByte(encryptedInput.at(i));
        decryptedOutput->at(i) = decryptedValue;
    }

    return move(decryptedOutput);
}
unique_ptr GetIV(整数计数器)
{
字节*计数器=(字节*)&计数器;
唯一_ptr iv(新向量());
对于(int j=0;j<4;j++)
{
iv->推回(对策[j]);
}
回迁(四);
}
唯一\u ptr加密(常量向量和明文输入)
{
unique_ptr encryptedOutput(新向量(plainInput.size());
对于(int i=0;idata(),_-key->size(),iv->data());
byte encryptedValue=encryptor.ProcessByte(plainInput.at(i));
encryptedOutput->at(i)=encryptedValue;
}
返回移动(加密输出);
}
唯一\u ptr解密(常量向量和加密输入,int位置)
{
唯一的\u ptr解密输出(新向量(encryptedInput.size());
对于(int i=0;idata(),_-key->size(),iv->data());
byte decryptedValue=decryptor.ProcessByte(encryptedInput.at(i));
decryptedOutput->at(i)=decryptedValue;
}
返回移动(解密输出);
}

如您所见,我遍历输入缓冲区中的所有字节,并分别加密\解密每个字节,因为每个块都必须有唯一的计数器(在CTR模式下)。因为我需要能够解密随机字节,所以我需要和缓冲区大小一样多的块,对吗?我的解决方案有效,但速度非常慢。。。我做得对吗?或者也许有更有效的方法来做这件事?

不,你做得不对。您根本不需要遍历decrypt方法的输入

您只需为包含要解密字节的块计算正确的计数器。然后你可以用这个计数器作为IV值。现在您可以加密或解密密文块并检索正确的字节。不需要单独解密特定字节


因此,如果密码的块大小为16,IV/nonce为
f00000000000000f00000000000000h
,字节偏移量为260,则计数器/IV需要提前260/16=16=10h。然后
f00000000000000f00000000000000h
+10h=
f00000000000000f00000000000010
。然后解密第16个块并在偏移量3处获取第4个字节(260%16=4)。

您的代码有几个主要问题:

  • 您正在使用未经验证的加密,这在大多数应用程序域中是不安全的。请改用
    AES-GCM
    ,它看起来很像
    AES-CTR
    。事实上,这是正确地提到了
  • CTR模式的IV是16字节长,但您只使用4个字节。您的代码不仅计算错误,而且表现出未定义的行为
  • IV是每个消息,而不是每个字节
  • 由于您选择的IV错误,您的算法基本上减少到一次性pad,但不安全。如果您使用同一密钥加密两条消息,系统将被破坏
性能问题是您最不关心的。整个实现都是不正确和不安全的在尝试使用密码学之前,您必须系统地学习密码学,因为这不是一个您可以通过反复尝试学习的领域。设计一个通过所有单元测试的系统是很容易的,在你看来很好,但在训练有素的人看来完全失败了


我推荐。

你也许应该去参观一下。可能相关:回答不错,除了您推荐AES-GCM而不是AES-CTR。这个问题非常明确,需要使用随机访问进行解密。认证模式不提供这一点。