AES加密计数器模式能否指定nonce和counter?

Can I specify the nonce and counter in AES encryption counter mode?

我正在尝试使用库 Crypto++ 制作基于 AES 计数器模式的 encryption/decryption

我想将 IV 值拆分为随机数和计数器。
有没有API直接拿nonce和counter构造IV的?

我做了以下实现它

byte counter[AES::BLOCKSIZE/2] = {0x0};     // initialized to zero : 64 bit counter
string counterstr ;
byte nonce[AES::BLOCKSIZE/2];                // 64 bit nonce 
string noncestr ;
prng.GenerateBlock(nonce, sizeof(nonce));
StringSource(nonce, sizeof(nonce), true,
    new HexEncoder(
    new StringSink(noncestr)
    ) // HexEncoder
    );
StringSource(counter, sizeof(counter), true,
    new HexEncoder(
    new StringSink(counterstr)
    ) // HexEncoder
    );
SecByteBlock no = HexDecodeString(noncestr);
SecByteBlock ctr = HexDecodeString(counterstr);
string ivv = noncestr + counterstr;
SecByteBlock ivvb = HexDecodeString(ivv);

然后我用

e.SetKeyWithIV(key, sizeof(key), iv);

问题:

Is this the only way to achieve this or is there any other easier way?

没有。递增函数对完整的 128 位块进行操作。请参阅 Crypto++ wiki 上的 CTR mode and Counter Increment

较长的答案是 如果 您提供自己的 IncrementCounter 函数。更长的答案可以是 if 你使用高位作为随机数,低位作为计数器(见下文)。


Does the counter value increment automatically when doing encryption or decryption of blocks?

是的。


This one is trivial, should I specify another nonce value for each block?

没有。计数器递增。


Is there any API that directly takes the nonce and counter to construct the IV ?

没有。更实际地说,在 key/nonce 对(或安全上下文)下可以加密多少纯文本是有限制的。我认为它远低于 2 GB。如果我没记错的话,那么在你的计数器进入高64位之前,你将不得不重新键入。

实际上,这意味着您可以使用高 64 位作为随机数,并使用低 64 位作为计数器。所以你的代码看起来像:

byte counter[AES::BLOCKSIZE] = {0};
prng.GenerateBlock(counter, 8);

上述代码执行后,高64位随机,低64位从0开始,作为计数器。

由于 2 GB 大约是限制,您可以使用 12-4 拆分而不是 8-8 拆分:

byte counter[AES::BLOCKSIZE] = {0};
prng.GenerateBlock(counter, 12);

上述代码执行后,高96位随机,低32位从0开始,作为计数器。


相关,切勿重复使用随机数。每条消息都必须有自己的、唯一的安全上下文。这通常意味着一个唯一的随机数(另一种选择是为每条消息提供一个唯一的密钥)。否则,您可以使用 XOR.

轻松恢复密钥