首页 > 解决方案 > 读取密码后覆盖 std::cin 读取缓冲区

问题描述

从 std::cin 读取密码后

std::cout << "Password: ";
SecureString pw{}; // secure string, wipes automatically on destruction
SetConsoleEcho(false); // hide input in terminal
std::getline(std::cin, pw); // input the password
SetConsoleEcho(true); // switch echo back on

密码一直存储在 cin(堆内存)的读取缓冲区中,直到它被新输入覆盖,并且可以很容易地被 Process Hacker 等工具嗅探,或者在内存转储的情况下被写入磁盘。

有谁知道 std::cin.rdbuf() 如何被清除/覆盖,理想情况下是跨平台的?或者有没有办法避免首先使用缓冲区?

上面的代码使用 SecureString,它是使用 Crypto++ 的 AllocatorWithCleanup 实现的,它在销毁时擦除内存。SetConsoleEcho 打开/关闭控制台回显,以避免在屏幕上看到纯文本密码。

我意识到这个问题与这个问题非常相似,但已经有 10 多年了,而公认的答案实际上并没有回答这个问题。

标签: c++securityterminalpasswordscin

解决方案


链接的帖子包含您需要的所有答案,不幸的是,没有一种方法可以安全地读取然后清除密码,密码被泄露的风险为 0。看

即使您立即在缓冲区上乱涂乱画,密码仍有可能写入磁盘。系统 i/o 缓冲区可能被分页到磁盘,std::cin 所在的工作内存也可能被分页到磁盘。我曾经开发过能够准确嗅出这些条件的取证软件。

此外,如果恶意行为者可以访问 PC,则可以使用键盘记录器来提取密码。


推荐阅读