首页 > 解决方案 > GCM 中的 Crypto++ AES 正在生成类似的密文

问题描述

我正在尝试实现正确且安全的准系统、从头到尾的 AES 加密。出于我的目的,我只想生成一些基准测试程序输出的密文,以模拟将写入什么样的密文,例如云存储服务器。在阅读了一些内容之后,我得出的结论是,出于我的目的,由 AES 在 GCM 模式下生成的经过身份验证的加密代表了我在真实服务器上使用的密文。

从 Crypto++ Wiki 页面上的示例代码开始,我想出了以下片段来从文件中读取一些字符串并转储密文。问题是我得到的密文非常相似,上半部分在许多输出中是相同的。我怀疑这是由于我使用/初始化 AutoSededRandomPool 的方式造成的,但我对此知之甚少,无法弄清楚如何修复它。看起来底层代码正在调用操作系统(Ubuntu 16.04)来生成熵,这让我相信调用之间可能没有足够的时间来改变这个值。

提前感谢您提供的任何帮助。

#include "osrng.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "hex.h"
#include "filters.h"
#include "aes.h"
#include "gcm.h"
#include "secblock.h"

using namespace std;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::AutoSeededX917RNG;
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
using CryptoPP::GCM;
using CryptoPP::SecByteBlock;

// Single randomly seeded RNG
AutoSeededRandomPool rnd;

// Generate a string buffer for the input/output data
string plainText, cipherText, encoded;

// Generate a random key
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

// Generate an initial value vector (public but unique per msg)
SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, iv.size());

for (size_t i = 0; i < numLines; ++i)
{
    getline(inputFileStream, plainText);

    // Do encryption
    GCM<AES>::Encryption e;
    e.SetKeyWithIV(key, key.size(), iv, iv.size());
    StringSource
    (
        plainText,
        true,
        new AuthenticatedEncryptionFilter
        (
            e,
            new StringSink(cipherText)
        )
    );

    encoded.clear();
    StringSource
    (
        cipherText,
        true,
        new HexEncoder
        (
            new StringSink(encoded)
        )
    );
    cout << "Cipher Text: " << encoded << endl;
}

以下是输出密文的示例:

密文:

9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6

密文:

9DE3A67D5FF42A15834460CD4489B20A352ECEB5F801F7349F3A989DAE8C02675CB48ADDD00604139353F2DEC6335DF8156DA66ACEF953F2E573BB3D88E7AF7D59EE311DC8056CDB0B90B30A232DD7ECB219FB2F9F2D9898B98A1B6749FC8B88D00B5E08DC4EF9C3A52521298D6FBFD75A9A71E8A253D8B9F06D17B07442DA543B8E1CCCEC1E7D7084A1A24DAA71CB688AC2ECD840731F5D57AA7BC61DE5837411596561C36659D95451A003A0E27697528B9BB6B67763F6D8B9F0691B616C2E996B5E473860EE348C09A1F0FC

将 IV 生成移到循环之外,有类似的行为:

密文:

25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87

密文:

25C638C32E67A7A2C65BF37ABA7C30C19C2714D95FBB68E6E57560CCE2C20F266E6C30768108CF7E01C195991B61AF7FE4F4FA691AFEAAFCFB74292EBE30B9236147722F5785D8F21070D3ACF9E476E39235B4C362D14BF7B2FC2A5BFC0297FCBCBEC37795626029CC30B404A6DB67EA652F5A7FA294D039C4A09BC611F74D8C9FFBD26F49C54470E2C41463440AF050D7FF160CD923FFD0CA6FAF1DB66947C5896B1A39A8E9B694A025E2F521229BDC15C48C5F3AD27A87FA3272CFE669E235CE452FCEEA59CC8CA34554FF25

以下答案的附录:

在代码中,我忽略了在循环的每次迭代中清除字符串“cipherText”。显然,StringSink 操作只是将新的密文附加到密文的末尾,这就是它们相同的原因。感谢所有的帮助!

标签: c++cryptographyc++17crypto++

解决方案


您正在 for 循环之外生成密钥和 IV。这意味着您将对正在加密的线路使用相同的密钥/IV 组合。GCM 基本上是带有身份验证标签的 CTR 加密。这意味着明文中相似的位将产生完全相同的值。只有在 IV从不重复的情况下,GCM 才是安全的。

将 IV 代放在循环中,你应该没问题。请注意,对于 GCM,12 字节 IV 比 16 字节 IV 更有效并且可能更安全。随机 IV 通常放在密文前面(通过StringSink手动写入)。

在您的原始代码中,您犯了两个错误。你打印了密钥而不是 IV,这让你相信你的 RNG 是错误的。此外,您在没有先清除它的情况下写入了ciphertext字符串变量。这使得StringSink将下一个密文(和身份验证标签)附加到ciphertext字符串。所以当你打印出来时,你得到了第一个和第二个密文。


推荐阅读