AES / CCM加密和纯文本长度超过最大消息长度

时间:2019-06-05 18:04:24

标签: c++ encryption crypto++

我正在尝试使用具有CCM操作模式的AES128密码在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)
);

当我尝试对CD大小为(737280000)的纯文本进行加密/解密时,出现以下错误:

  

”终止在引发“ CryptoPP :: InvalidArgument”实例后调用     what():AES / CCM:消息长度737280000超过了最大值16777215“

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

1 个答案:

答案 0 :(得分:3)

  

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

在NIST SP800-38c中指定了CCM模式。第A.1节“长度要求”讨论了安全性上下文下的最大纯文本。安全上下文是 {key,iv} 组合(有些弃权)。

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

第二,您必须重新键入键或更改iv,然后才能在上下文中找到最大的纯文本。您可以使用MaxMessageLength()找到最大的纯文本长度。 Crypto ++跟踪通过m_totalMessageLength处理的字节数,但不会暴露给用户程序。您必须自己进行跟踪。

第三,您可以更改算法。像ChaCha20Poly1305这样的算法可让您加密2 ^ 38-1个64字节的块。不到2 ^ 44字节或大约256 GB。 ChaCha20Poly1305应该很安全。


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

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

MaxMessageLength()authenc.cpp中使用。达到限制时,ProcessData()引发异常:

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;

您的标签尺寸偏小。如果协议允许,则可能要使用最大大小。


我建议您切换算法。 CCM是一种混蛋模式,它在2000年初通过一些无线工作组进行了标准化。然后,NIST采纳了它,因为它已经标准化了。

在CCM标准化时,有更好的Authenticated Encryption模式可用,例如CWC,OCB,EAX和GCM。不幸的是,损坏已经造成。现在您有了像Bernstein的ChaChaPoly1305这样的算法。

您可能还想在Crypto ++ Wiki上检出AEAD Comparison。比较表明,CCM大约是经过身份验证的加密模式中最差的。