如何确保编译器优化不会带来安全风险?
我必须编写一个 Windows 服务来处理机密数据(例如 PIN 码、密码等).在很短的时间内需要这些信息:通常它们几乎会立即发送到智能卡读卡器.
I have to write a Windows service that handles at some point confidential data (such as PIN codes, passwords, and so on). Those informations are needed for a very short amount of time: usually they are sent almost immediately to a smart card reader.
让我们考虑这段代码:
{
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 '' so it doesn't stay in memory.
std::fill(password.begin(), password.end(), '');
}
现在我关心的是编译器优化.这里编译器可能会检测到密码即将被删除,此时更改其值没有用,只需删除调用即可.
Now my concern is about compiler optimizations. Here the compiler might detect that password is about to be deleted and that changing its value at this point is useless and just remove the call.
我不希望我的编译器关心未来未引用内存的价值.
I don't expect my compiler to care about the value of future-unreferenced memory.
我的担忧是否合理?我怎么能确定这样一段代码不会被优化掉?
Are my concerns legitimate ? How can I be sure that such a piece of code won't be optimized-out ?
推荐答案
是的,您的担忧是合理的.您需要使用专门设计的函数,例如 SecureZeroMemory() 防止优化修改您的代码行为.
Yes, your concerns are legitimate. You need to use specifically designed function like SecureZeroMemory() to prevent optimizations from modifying your code behavior.
不要忘记字符串类应该是专门为处理密码而设计的.例如,如果类重新分配缓冲区以保存更长的字符串,则必须先擦除缓冲区,然后再将其返回到内存分配器.我不确定,但很可能 std::string
不会这样做(至少在默认情况下).使用不合适的字符串处理类会使您的所有担忧变得毫无价值 - 您甚至会在知道之前将密码复制到整个程序内存中.
Don't forget that the string class should have been specifically designed for handling passwords. For example, if the class reallocates the buffer to hold a longer string it has to erase the buffer before retunring it to the memory allocator. I'm not sure, but it's likely std::string
doesn't do that (at least by default). Using an unsuitable string handling class makes all your concerns worthless - you'll have the password copied all over the program memory befoe you even know.
相关文章