我可以对 std::array 使用自定义分配器来获取安全加密密钥吗?
Can I use a custom allocator for std::array for secure cryptographic keys?
我知道std::array
完全在堆栈中分配,但这个问题的动机是安全问题,需要两件事:
std::array
中的数据将在销毁时归零或随机化std::array
中的数据将被锁定,这样它就不会在崩溃或交换内存时进入磁盘
通常,使用std::vector
,解决方案是创建一个执行这些操作的自定义分配器。但是,对于std::array
,我不明白如何做到这一点,因此这个问题。
我能做的最好的事情就是:
template <typename T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
static_assert(std::is_pod<T>::value, "Only POD types allowed")
static_assert(sizeof(T) == 1, "Only 1-byte types allowed")
virtual ~SecureArray()
{
std::vector<uint8_t> d = RandomBytes(Size); // generates Size random bytes
std::memcpy(this->data(), d.data(), Size);
}
}
但这显然缺乏内存锁定,并且使首先使用std::array
获得的std::array
性能方案复杂化。
有没有更好的解决方案?
std::array
不能使用分配器;但是,似乎您的 SecureArray 类可以通过自定义构造函数/解构函数实现您想要的。
像这样:
#include <sys/mman.h>
template<class T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
// Your static_asserts...
SecureArray(void) {
mlock(std::array<T, Size>::data(), sizeof(T) * Size);
}
~SecureArray(void) {
char *bytes = reinterpret_cast<char *>(std::array<T, Size>::data());
for (std::size_t i = 0; i < sizeof(T) * Size; i++)
bytes[i] = 0;
munlock(bytes, sizeof(T) * N);
}
};
我知道
std::array
完全在堆栈中分配
这并不完全正确。std::array
不会分配任何内存,因此这取决于您分配内存的位置。
auto* arr = new std::array<int, 100>(); // BUM! it is allocated on the heap
但这显然缺乏内存锁定,并且使首先使用
std::array
获得的std::array
性能方案复杂化。
首先,锁定堆栈上的内存不是问题。参见 POSIX 示例:
#include <iostream>
#include <sys/mman.h>
#include <array>
int main()
{
std::array<int, 3> a = {1, 2, 3}; // std::array allocated on the stack
if (mlock(a.data(), sizeof(a)) == 0)
{
std::cout << "LOCKED" << std::endl;
}
}
因此,您可以在构造函数中调用mlock
或任何便携式模拟SecureArray
。
其次,您希望获得什么性能提升?内存读取/写入速度不取决于您在何处分配阵列、堆或堆栈。因此,这完全取决于您分配和锁定内存的速度。如果性能至关重要,则内存锁定可能太慢(或者不是,谁知道呢?(,即使堆栈上分配了内存,也无法SecureArray
构造函数中每次调用它。
因此,将std::vector
与自定义分配器一起使用会更方便。它可以预分配和预锁大内存块,因此分配速度几乎与堆栈上一样快。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- C++为构建时间获取QDateTime的可靠方法
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 使用指针从C++中的数组中获取最大值
- 如何获取std::result_of函数的返回类型
- 如何在openssl-ecc中获取十六进制格式的私钥
- 使用Unreal C++获取VR耳机的世界位置/方向
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 在 c++ 中从执行的 shell 命令获取返回状态的安全方法是什么?
- 我可以对 std::array 使用自定义分配器来获取安全加密密钥吗?
- ssl3_read_bytes:TLSV1警报内部错误,安全套接字,OpenSSL,C ,获取HTTPS页面
- 使用安全模式从DLL(通过(INTPTR)参数传递到该函数)获取char **
- 在 C++20 中获取当前日期/时间是否线程安全?
- 使用安全_vsnprintf_s获取所需的缓冲区长度
- 如何获取内核对象的安全描述符
- 在移动之前获取右值引用的地址被认为是安全的
- 如何处理必须以异常安全方式获取多个资源的构造函数