AES-gcm 加密的 IV 中是否有不起作用的值?

Are there values in IVs for AES-gcm encryption which are just not working?

我正在使用 Openssl EVP 通过 aes-gcm-256 加密、解密明文。我提供了一个空字符串作为附加数据,并且每次使用 RAND_bytes 随机生成 IV。我的 IV 长 16 个字节。密钥是静态的,就像明文一样。所以每个 运行 唯一不同的是 IV。如果我将这个程序循环 10.000 次,它大约有 82% 的时间可以工作。是否有可能某些值在包含在 IV 中时不起作用?

以下是一些无效的 IV:(以十六进制格式提供以便于阅读)

868DCDA3B6A47F9461CEFC1CF096E419    
942A3E63CB22BFFCF4309B038575D9DF    
7DABF472A03FCFD4AA88A17BF17049B5    
10E94264C5133011665978290D157FDF    
B33323638D679A4CDD17844C5E50A656    
D77CA61F54374F8AF76BF625F6065317    
A81C1087C2218E29DB5DBBE3DF31CF03    
15678C7484E20DD2C4BDB9E67D4FA7AD    
3DC18C3AAFE48367905091D6C760A2CA    
9940CA7685B92C46F716FE3E3EDD4675    
CA2E9EBACD824F06523A7471ABB1A637    
691D54DB476FF73C27D19B0BFD7191D2    
020FF1C6702BCF5D8715082768B14CC8    
F72623956640DDA62047821E3418F1EC    
743F1B9A8AF46D8EC2472DD44059E87E    
6CC0C96CFEA33DC96B9C8FB27587A6B6    
2A73F05FC73AB2BE0D3B78FD65824100    
0D44B61773986D5C4E11521121A9D7BF    
DEB9896F1EACE3B8F10F980595108578    
4AA5B4922564E664C67BC83B58C18A94    
AFF764905CAD86EF7ABA582853EAD2F5    
FD4C09E91EA36024E8BA8D4D5FA6751E    
5F764A3F0217EAA54D242E28C7E45640    
5ED5B3C23DF30E178517FAB51F28DE32    
34E9B4CF4E2149EBF919F75D9374267A    
31D65E7E61D888CF4C244B009B71117C

当然还有很多。如果有人知道我将非常感激。

int successful = 0;
for (int i = 1; i < 10001; ++i)
{
    unsigned char *key = (unsigned char *)"01234567890123456789012345678901";

    /* Message to be encrypted */
    unsigned char *plaintext = (unsigned char *)"The quick brown fox jumps over the lazy dog";

    unsigned char ciphertext[128];

    /* Buffer for the decrypted text */
    unsigned char decryptedtext[128];

    /* Buffer for the tag */
    unsigned char tag[16];

    int decryptedtext_len, ciphertext_len;

    //initialize random number generator (for IVs)
    int rv = RAND_load_file("/dev/urandom", 32);

    a:
    /* A 128 bit IV */
    size_t iv_len = 16;
    unsigned char iv[iv_len];
    RAND_bytes(iv, sizeof(iv));

    ciphertext_len = gcm_encrypt(plaintext, key, iv, iv_len, ciphertext, tag);

    decryptedtext_len = gcm_decrypt(ciphertext, tag, key, iv, iv_len, decryptedtext);

    if (decryptedtext_len >= 0)
    {
        /* Add a NULL terminator. We are expecting printable text */
        decryptedtext[decryptedtext_len] = '[=11=]';

        ++successful;
        std::string dec(reinterpret_cast<char *>(iv), iv_len);
        //std::cout << (float)successful / i << " " << string_to_hex(dec) << "\n";
    }
    else
    {
        //printf("Decryption failed\n");
        std::string dec(reinterpret_cast<char *>(iv), iv_len);
        std::cout << string_to_hex(dec) << "\n";
        goto a;
    }
}

std::cout << (float)successful / 10000 << "\n";

gcm_encrypt 和 gcm_decrypt 函数与文档中使用的函数类似。我只是改变了函数本身计算长度,

https://wiki.openssl.org/images/0/08/Evp-gcm-encrypt.c

You appear not to be passing the ciphertext length to your decrypt function, how does it know how much ciphertext there is to decrypt? If you're just using strlen() or the like, what happens when the ciphertext contains a 0x00 byte? -- Iridium

这解决了我的问题,谢谢。