这个问题遵循@sharptooth在this related question中提出的建议。
可以调整std::string
以使其变得密码安全吗?
如果没有,编写密码处理类的指导原则是什么(因此这个类需要非常注意写入内存并在销毁之前将其清除)?
答案 0 :(得分:20)
是的,首先定义一个自定义分配器:
template <class T> class SecureAllocator : public std::allocator<T>
{
public:
template<class U> struct rebind { typedef SecureAllocator<U> other; };
SecureAllocator() throw() {}
SecureAllocator(const SecureAllocator&) throw() {}
template <class U> SecureAllocator(const SecureAllocator<U>&) throw() {}
void deallocate(pointer p, size_type n)
{
std::fill_n((volatile char*)p, n*sizeof(T), 0);
std::allocator<T>::deallocate(p, n);
}
};
此分配器在释放之前将内存清零。现在你输入type:
typedef std::basic_string<char, std::char_traits<char>, SecureAllocator<char>> SecureString;
然而,存在一个小问题,std :: string可能会使用小字符串优化并在其内部存储一些数据,而无需动态分配。因此,您必须在销毁时明确清除它或使用我们的自定义分配器在堆上进行分配:
int main(int, char**)
{
using boost::shared_ptr;
using boost::allocate_shared;
shared_ptr<SecureString> str = allocate_shared<SecureString>(SecureAllocator<SecureString>(), "aaa");
}
这可以保证在重新分配之前将所有数据归零,例如包括字符串的大小。