AES CTR 模式 - encryption\decryption with Crypto++ - 我做得对吗?

AES CTR mode - encryption\decryption with Crypto++ - am I doing it right?

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

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);
}

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

不,你这样做不对。您根本不需要遍历解密方法的输入。

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

所以如果密码的块大小是 16,IV/nonce 是 F000000000000000F000000000000000h 并且字节的偏移量是 260 那么 counter/IV 需要用 260 / 16 = 16 = 10 小时。然后 F000000000000000F000000000000000h + 10h = F000000000000000F000000000000010。然后你解密第 16 个块并在偏移量 3 处取第 4 个字节(如 260 % 16 = 4)。

您的代码存在几个主要问题:

  • 您正在使用未验证 加密,这在大多数应用程序域中都是不安全的。请改用 AES-GCM,它看起来很像 AES-CTR。这实际上在 documentation of Crypto++.
  • 上提到了
  • CTR模式的IV长16字节,你只用了4字节。您的代码不仅计算错误,而且还表现出未定义的行为。
  • IV 是 每条消息,而不是每字节。
  • 因为你选择了错误的IV,你的算法基本上减少到一次一密,除了不那么安全。如果您曾经使用相同的密钥加密两条消息,系统就会崩溃。

性能问题是您最不关心的问题。整个实现是不正确和不安全的。 在尝试使用它之前,您必须系统地学习密码学,因为它不是您可以通过反复试验来学习的领域。设计一个通过所有单元测试并且在您自己看来还不错,但在受过训练的人看来却完全损坏的系统很容易。

我推荐cryptography on coursera