来自 Crypto++ 的 SecByteBlock 类的优点

use*_*614 5 c++ cryptography crypto++

我正在使用 Crypto++ 库在 CBC 模式下使用 AES 算法解密文件。我SecByteBlock在AES 的示例代码中遇到了类,它说

使用 SecByteBlock 在堆栈上声明密钥以确保敏感材料归零。

有人可以解释我什么时候SecByteBlock会清除内容以及这个课程提供什么优势char*

提前致谢

jww*_*jww 7

[title] 来自 Crypto++ 的 SecByteBlock 类的优点

使用的优点SecByteBlock是您可以通过归零获得托管缓冲区。归零通常是合规性项目。例如,FIPS 140-2 要求它,即使在级别 1 验证中也是如此。

第二个不明显的好处是分配器初始化 POD 内存——它返回一个原始块。这很有意义,因为您经常初始化一个 0 值,然后用数据覆盖内容。初始化它没有任何意义,它节省了大量时间。

您可以SecBlock提供一个 0 值的初始化块。以下是两者的方法:

SecByteBlock block1(32);
SecByteBlock block2(NULL, 32);
Run Code Online (Sandbox Code Playgroud)

block1 大小为 32 字节,未初始化,其内容将是垃圾。

block2大小也是 32 字节,但它使用了(ptr, size)重载。重载将复制 指向的块ptr,或者如果它的NULL.


为了完整性和参考性, aSecByteBlock只是SecBlock<byte>. SecBlock<T>是阶级的利益,图书馆经常使用SecBlock<byte>SecBlock<word32>SecBlock<word64>,等。

这是 Doxygen 生成的手册页SecBlockSecBlock< T, A > Class Template Reference。这是secblock.h的头文件(它只是一个头文件实现)。


当内容SecByteBlock被清除时,有人可以解释我吗?

SecByteBlock在明显的对象销毁情况下,的内容被清除。也就是说,SecBlock当析构函数运行时,分配给 的内存会以0 的模式清除。

有一个不明显的情况,那resize就是调用缩小一个的时候。在这种情况下,返回给操作系统的额外空间也会被擦除。

您可以在源代码中看到擦除。例如,来自Crypto++ 5.6.4 secblock.h

SecByteBlock block1(32);
SecByteBlock block2(NULL, 32);
Run Code Online (Sandbox Code Playgroud)

这个类比 char* 有什么优势。

嗯,这SecBlock<byte>是一个管理缓冲区的类。char*只是一种类型,并没有太多内容。您必须管理char*指向的缓冲区。

您可以使用类似 a 的东西std::string,但您不会得到溢出检测(只std::vector需要检查它)并且您不会得到归零。

话虽如此,您可以同时执行以下两项操作:

  • typdef SecBlock<char> SecCharBlock
  • typedef std::basic_string<char, std::char_traits<char>, AllocatorWithCleanup<char> > secure_string

第二个有点酷。您可以这样做,因为secblock.h提供了一个与标准库兼容的安全分配器。SecBlock<T>在内部使用安全分配器,它被称为AllocatiorWithCleanup<T>.

OpenSSL 的关于EVP 对称加密和解密的 wiki 页面| C++ Progamssecure_string在他们的示例中使用类似的分配器来提供一个类。OpenSS:的zallocator电话OpenSSL_cleanse

来自Crypto++ 5.6.4 secblock.h

  187     //! \brief Deallocates a block of memory
  188     //! \param ptr the pointer for the allocation
  189     //! \param size the size of the allocation, in elements
  190     //! \details Internally, SecureWipeArray() is called before deallocating the memory.
  191     //!   Once the memory block is wiped or zeroized, AlignedDeallocate() or
  192     //!   UnalignedDeallocate() is called.
  193     //! \details AlignedDeallocate() is used if T_Align16 is true.
  194     //!   UnalignedDeallocate() used if T_Align16 is false.
  195     void deallocate(void *ptr, size_type size)
  196     {
  197         CRYPTOPP_ASSERT((ptr && size) || !(ptr || size));
  198         SecureWipeArray((pointer)ptr, size);
  199 
  200 #if CRYPTOPP_BOOL_ALIGN16
  201         if (T_Align16 && size*sizeof(T) >= 16)
  202             return AlignedDeallocate(ptr);
  203 #endif
  204 
  205         UnalignedDeallocate(ptr);
  206     }
Run Code Online (Sandbox Code Playgroud)