ere*_*eOn 39 c++ memory compiler-construction security optimization
我必须编写一个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)
现在我关心的是编译器优化.在这里,编译器可能会检测到密码即将被删除,并且此时更改其值是无用的,只需删除该调用即可.
我不希望我的编译器关心未来未引用的内存的价值.
我的担忧是否合法?我怎么能确定这样的代码不会被优化?
sha*_*oth 34
是的,您的担忧是合法的.您需要使用SecureZeroMemory()等专门设计的函数来防止优化修改代码行为.
不要忘记字符串类应该是专门为处理密码而设计的.例如,如果类重新分配缓冲区以保存更长的字符串,则必须先擦除缓冲区,然后再将其重新调整到内存分配器.我不确定,但它可能std::string不会这样做(至少在默认情况下).使用不合适的字符串处理类会使您的所有问题变得毫无价值 - 您甚至可以在程序内存中复制密码.
这是有问题的,但另一个原因.谁说std::string password = getPassword();不会在记忆中留下另一份副本?(可能你需要在"destruct"或"deallocate"上为这个零内存写一个"安全"的分配器类)
在您的代码安静中,您可以通过获取指向字符串数据的易失性指针(我不知道您是否可以以标准方式执行)来避免优化,然后将数据归零.
不要使用std::string密码,因为在进行重新分配或破坏时它不会将其内存归零 - ConfidentialString而是设计自己的类.在设计该类时,您可能希望利用CryptProtectMemory ...并且在需要使用解密版本时非常非常小心,尤其是在调用外部代码时.
| 归档时间: |
|
| 查看次数: |
2495 次 |
| 最近记录: |