AES/CCM 加密和明文长度超过最大消息长度
AES/CCM Encryption and Plaintext Length Exceeds Maximum Message Length
我正在尝试使用 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)
);
当我尝试 encrypt/decrypt 一张 CD (737280000) 大小的明文时,出现以下错误:
"terminate called after throwing an instance of 'CryptoPP::InvalidArgument'
what(): AES/CCM: message length 737280000 exceeds the maximum of 16777215"
我的问题是,如何 encrypt/decrypt 一个超过 16777215 字节的明文?
My question is, how do I encrypt/decrypt a plaintext which is longer than 16777215 bytes?
CCM 模式在 NIST SP800-38c 中指定。 A.1 节,长度要求,讨论安全上下文下的最大纯文本。安全上下文是 {key, iv} 组合(需要一些手)。
我相信你有三个选择。首先,您可以增加 IV 的长度。 iv 越大,可以加密的明文越多。最大 iv 长度为 13,因此它不会永远扩展。
其次,您必须re-key或在达到上下文下的最大纯文本之前更改iv。您可以使用 MaxMessageLength()
. Crypto++ tracks the number of bytes processed via 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 是最差的经过身份验证的加密模式。
我正在尝试使用 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)
);
当我尝试 encrypt/decrypt 一张 CD (737280000) 大小的明文时,出现以下错误:
"terminate called after throwing an instance of 'CryptoPP::InvalidArgument' what(): AES/CCM: message length 737280000 exceeds the maximum of 16777215"
我的问题是,如何 encrypt/decrypt 一个超过 16777215 字节的明文?
My question is, how do I encrypt/decrypt a plaintext which is longer than 16777215 bytes?
CCM 模式在 NIST SP800-38c 中指定。 A.1 节,长度要求,讨论安全上下文下的最大纯文本。安全上下文是 {key, iv} 组合(需要一些手)。
我相信你有三个选择。首先,您可以增加 IV 的长度。 iv 越大,可以加密的明文越多。最大 iv 长度为 13,因此它不会永远扩展。
其次,您必须re-key或在达到上下文下的最大纯文本之前更改iv。您可以使用 MaxMessageLength()
. Crypto++ tracks the number of bytes processed via 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 是最差的经过身份验证的加密模式。