C++ 从std::cin读取密码

C++ 从std::cin读取密码,c++,stl,password-protection,C++,Stl,Password Protection,我需要从标准输入读取密码,并希望std::cin不回显用户键入的字符 如何从std::cin禁用回显 以下是我当前使用的代码: string passwd; cout << "Enter the password: "; getline( cin, passwd ); 我正在寻找一种操作系统不可知的方法来实现这一点。 在Windows和*nix中都有这样做的方法 标准中没有这方面的规定 在unix中,您可以根据终端类型编写一些神奇的字节 如果可用,请使用 在unix上,可以使用sy

我需要从标准输入读取密码,并希望std::cin不回显用户键入的字符

如何从std::cin禁用回显

以下是我当前使用的代码:

string passwd;
cout << "Enter the password: ";
getline( cin, passwd );
我正在寻找一种操作系统不可知的方法来实现这一点。
在Windows和*nix中都有这样做的方法

标准中没有这方面的规定

在unix中,您可以根据终端类型编写一些神奇的字节

如果可用,请使用

在unix上,可以使用system/usr/bin/stty-echo禁用echo,也可以使用/usr/bin/stty-echo再次启用它


如何在不使用stty的情况下完成;我自己没有试过。

我只知道我有什么,你可以一个字符一个字符地读取密码,然后打印backspace\b和“*”。

如果你不关心可移植性,你可以在VC中使用_getch


还有用于宽字符的getwch。我的建议是,您也可以使用*nix系统中提供的。wrang wrang回答非常好,但没有满足我的需要,这是我最终基于的代码的样子:

#ifdef WIN32
#include <windows.h>
#else
#include <termios.h>
#include <unistd.h>
#endif

void SetStdinEcho(bool enable = true)
{
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
    DWORD mode;
    GetConsoleMode(hStdin, &mode);

    if( !enable )
        mode &= ~ENABLE_ECHO_INPUT;
    else
        mode |= ENABLE_ECHO_INPUT;

    SetConsoleMode(hStdin, mode );

#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if( !enable )
        tty.c_lflag &= ~ECHO;
    else
        tty.c_lflag |= ECHO;

    (void) tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}
示例用法:

#include <iostream>
#include <string>

int main()
{
    SetStdinEcho(false);

    std::string password;
    std::cin >> password;

    SetStdinEcho(true);

    std::cout << password << std::endl;

    return 0;
}

我想getpasswd真的会有帮助。但我正在寻找一种方法来做到这一点,而不必重复操作系统的黑色魔法。如果有人将终端输出记录到一个文件中,那么整个密码都会在那里。也许这不是个好主意,就像有人记录所有按键一样:这是不安全的,也是个坏主意。依靠管道的另一端来保障自己的安全是不可接受的。注意不要在网络上铺设管道。和日志输出!=logging keypress:您通常会将日志文件的读取用户权限授予更多的人,而不是那些有权通过终端仿真器程序进行写入的人,或者连接到终端或系统事件或键盘驱动程序。gcc警告:home/curtine/git/pub/sxx/src/sxx.cpp:在函数“void set\u stdin\u echobool”中:/home/curtine/git/pub/sxx/src/sxx.cpp:84:19:错误:负整数隐式转换为无符号类型[-Werror=符号转换]tty.c\u lflag&=ECHO;要禁用该警告,我认为这是一个很好的答案,就不回显方面而言,但我已经否决了它,因为它将密码读入一个不安全的std::字符串,请参见例如。你会考虑把它改写成一个字符吗?在这种情况下,我很乐意推翻我的反对票。另外,关于@ericcurtin的评论,我发现&=~0u | ECHO是一种比简单地禁用警告更好的避免警告的方法。不过很有趣-$StackOverflow并不是专业的安全建议,只是提醒大家阅读。也就是说,@nickform,您可以轻松地将std::cin替换为char缓冲区[BUF_SIZE];fgetsbuffer,BUF_尺寸,标准尺寸;但是,正如Eric指出的,您需要安全地重写缓冲区,如果您要手动重写缓冲区,还可以使用std::string。您不能做的事情是创建一个类,该类将自动为您从std::string派生。
#include <iostream>
#include <string>

int main()
{
    SetStdinEcho(false);

    std::string password;
    std::cin >> password;

    SetStdinEcho(true);

    std::cout << password << std::endl;

    return 0;
}