此問題遵循@sharptooth在this related question中提出的建議。如何編寫密碼安全的類?
std::string
可以調整,以便它變成密碼安全的嗎?
如果不是,編寫密碼處理類的準則是什麼(因此一個類需要非常小心它寫入內存的內容並在破壞前清除它)?
此問題遵循@sharptooth在this related question中提出的建議。如何編寫密碼安全的類?
std::string
可以調整,以便它變成密碼安全的嗎?
如果不是,編寫密碼處理類的準則是什麼(因此一個類需要非常小心它寫入內存的內容並在破壞前清除它)?
是,首先定義一個自定義分配器:
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);
}
};
這個分配器重新分配之前歸零內存。現在您的typedef:
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");
}
這可以保證所有的數據被釋放之前歸零,包括字符串的大小,例如。
不要使用'std :: fill_n',使用類似'SecureZeroMemory()'(http://msdn.microsoft.com/en-us/library/aa366877(VS.85).aspx) - 與'std :: fill_n'編譯器可能會優化刪除。 – sharptooth 2010-09-24 09:21:09
當調用代碼導致字符串縮短時,強制'std :: string'擦除空格 - 例如刪除前N個元素,因此尾部移動「向左」並在右側留下字符「 「? – sharptooth 2010-09-24 09:22:01
@sharptooth SecureZeroMemory不是標準的,volatile會阻止優化。是的,如果沒有系統調用,則在CPU刷新緩存之前,有些數據可能會保留在內存中。 – ybungalobill 2010-09-24 09:23:50
1)使用std:wstring,2)按0x2022而不是密碼符號:o)嚴重的是,如果您擔心其他進程從您的內存中嗅探到某些內容,請添加/刪除一些掩碼(xor?) – alxx 2010-09-24 09:04:12
@alxx :如何使用'std :: wstring'而不是'std :: string'更安全?!我錯過了什麼嗎? – ereOn 2010-09-24 09:06:18
0x2022是子彈符號。得到它? :) – alxx 2010-09-24 09:10:46