我必须编写一个Windows服务,在某些时候处理机密数据(如PIN码,密码等).这些信息需要很短的时间:通常它们几乎立即被发送到智能卡读卡器.
让我们考虑这段代码:
{
std::string password = getPassword(); // Get the password from the user
writePasswordToSmartCard(password);
// Okay, here we don't need password anymore.
// We set it all to '\0' so it doesn't stay in memory.
std::fill(password.begin(), password.end(), '\0');
}
Run Code Online (Sandbox Code Playgroud)
现在我关心的是编译器优化.在这里,编译器可能会检测到密码即将被删除,并且此时更改其值是无用的,只需删除该调用即可.
我不希望我的编译器关心未来未引用的内存的价值.
我的担忧是否合法?我怎么能确定这样的代码不会被优化?
如何存储敏感数据(例如:密码)std::string?
我有一个应用程序,提示用户输入密码,并在连接设置期间将其传递给下游服务器.我想在建立连接后安全地清除密码值.
如果我将密码存储为char *数组,我可以使用SecureZeroMemory等 API 来清除进程内存中的敏感数据.但是,我想在代码中避免使用char数组,并且正在寻找类似的东西std::string?
问题在于:您的程序暂时使用了一些敏感数据,并希望在不再需要时删除它.使用std::fill()on本身并不总是有用 - 编译器可能会决定以后不访问内存块,因此擦除它是浪费时间并消除擦除代码.
用户ybungalobill建议使用volatile关键字:
{
char buffer[size];
//obtain and use password
std::fill_n( (volatile char*)buffer, size, 0);
}
Run Code Online (Sandbox Code Playgroud)
目的是在看到volatile关键字后,编译器不会尝试消除对该调用的调用std::fill_n().
请问volatile关键字总是会阻止编译器修改代码吗?
我正在尝试在类析构函数中安全地将a 归零。std::array从安全角度来说,我的意思是我想确保编译器永远不会优化此归零。这是我带来的:
template<size_t SZ>
struct Buf {
~Buf() {
auto ptr = static_cast<volatile uint8_t*>(buf_.data());
std::fill(ptr, ptr + buf_.size(), 0);
}
std::array<uint8_t, SZ> buf_{};
};
Run Code Online (Sandbox Code Playgroud)
这段代码是否按预期工作?在任何情况下该volatile关键字都会阻止编译器优化吗?