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 函数与文档中使用的函数类似。我只是改变了函数本身计算长度,
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
这解决了我的问题,谢谢。
我正在使用 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 函数与文档中使用的函数类似。我只是改变了函数本身计算长度,
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
这解决了我的问题,谢谢。