C++ AES/CCM加密和明文长度超过最大消息长度

C++ AES/CCM加密和明文长度超过最大消息长度,c++,encryption,crypto++,C++,Encryption,Crypto++,我正在尝试使用AES128密码和CCM操作模式在Crypto++库中执行加密和解密。当我尝试加密长度超过16777215字节的字符串时出现问题 我的代码: const int TAG_SIZE = 8; CCM< AES, TAG_SIZE >::Encryption e; CCM< AES, TAG_SIZE >::Decryption d; e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) ); e.SpecifyDa

我正在尝试使用AES128密码和CCM操作模式在Crypto++库中执行加密和解密。当我尝试加密长度超过16777215字节的字符串时出现问题

我的代码:

const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;

e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
e.SpecifyDataLengths( 0, plain.size(), 0 );

//Encryption
StringSource ss1(
  plain,
  true,
  new AuthenticatedEncryptionFilter(
    e,
    new StringSink(cipher)
   )
);

d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
d.SpecifyDataLengths( 0, plain.size(), 0 );

//Decryption
AuthenticatedDecryptionFilter df( d,
  new StringSink(recovered)
);
StringSource ss2(
  cipher,
  true,
  new Redirector(df)
);
const int TAG_SIZE=8;
CCM:加密e;
CCM:解密d;
e、 SetKeyWithIV(key,sizeof(key),iv,sizeof(iv));
e、 指定长度(0,plain.size(),0);
//加密
StringSource ss1(
平原
是的,
新的AuthenticatedEncryptionFilter(
E
新字符串接收器(密码)
)
);
d、 SetKeyWithIV(key,sizeof(key),iv,sizeof(iv));
d、 指定长度(0,plain.size(),0);
//解密
AuthenticatedDecryptionFilter df(d,
新的StringSink(已恢复)
);
StringSource ss2(
密码,
是的,
新重定向器(df)
);
当我尝试加密/解密一张CD大小的明文(737280000)时,我得到以下错误:

“在抛出'CryptoPP::InvalidArgument'实例后调用terminate” what():AES/CCM:消息长度737280000超过最大值16777215“

我的问题是,如何加密/解密长度超过16777215字节的明文

我的问题是,如何加密/解密长度超过16777215字节的明文

NIST规定了CCM模式。第A.1节“长度要求”讨论了安全上下文下的最大纯文本。安全上下文是{key,iv}组合(有一些手动放弃)

我相信你有三个选择。首先,可以增加IV的长度。IV越大,可以加密的纯文本越多。最大iv长度为13,因此不会永远增大

其次,在达到上下文下的最大纯文本之前,必须重新设置或更改iv键。您可以使用查找最大纯文本长度。Crypto++跟踪通过处理的字节数,但不向用户程序公开。你必须自己跟踪它

第三,你可以改变算法。类似的算法允许您加密2^38-1 64字节块。这略低于2^44字节或约256 GB。使用ChaCha20Poly1305应该是安全的


Crypto++通过告诉您最大字节数。在CCM的情况下,它基于iv长度,并通过下面代码中的
m_L
进行跟踪

lword MaxMessageLength() const
    {return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}

const int TAG_SIZE=8;
CCM:加密e;
CCM:解密d;
你的标签尺寸有点小。如果协议允许,您可能希望使用最大大小


我建议您切换算法。CCM是一种私生子模式,在2000年初通过一些无线工作组实现了标准化。然后,NIST采用了它,因为它已经标准化了

在CCM标准化时,有更好的模式可用,如CWC、OCB、EAX和GCM。不幸的是造成了损害。现在你有了像伯恩斯坦的ChaChaPoly1305这样的算法

您可能还希望在Crypto++wiki上签出。比较表明,CCM是最差的认证加密模式

if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength)
    throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
m_totalMessageLength += length;
const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;