如何在终端上以星号(*)的形式显示输入密码

问题描述 投票:11回答:3

我想写一个简单的C程序来验证password,例如,如果密码等于1234,那么我想打印欢迎,否则再试一次。但问题如下:

我想以*(星号)的形式显示输入密码。例如..如果用户输入1234,它将显示为****,以避免其他人看到输入的密码。

任何人都可以给我一个如何使用c或c ++实现它的想法。平台:UNIX

c++ c unix
3个回答
17
投票

不幸的是,解决方案是特定于平台的。

在Linux或BSD上,你可以使用readpassphrase函数(还有getpass,虽然它不允许调用者提供缓冲区和缓冲区大小.GNU Lib C的文档(链接损坏?尝试this alternative)库也提供了一个很好的指导,说明如何根据较低级别的termios原语实现这一点,您可以在其他UNIX实现上使用它来代替getpass)。

在Windows上,您可以使用SetConsoleMode禁用默认的回显行为(从而回显您自己的字符,如星号)。然后,您可以使用SetConsoleMode恢复回显。

但是,我应该补充一点,这是一种非常糟糕的身份验证形式,因为它涉及更多密码,这是每个用户存在的祸根(也不是特别安全)。更好的方法是在应用程序中启动Web服务器并输出用户应在其上进行身份验证的URL。这种方法的优点是,当用户导航到此URL时,该URL可以支持委托登录到第三方身份提供商,例如Google,Facebook,Twitter等。即使您不支持第三方身份提供商,这种方法带来了其他好处;如果您有其他基于Web的工具,这种方法可以减少用户必须进行身份验证的次数(因为命令行工具和基于Web的工具将共享相同的浏览器会话)并允许您仅实现一次登录流程,这种方法还可以减轻网络钓鱼风险(用户可以在输入凭据时明显看到浏览器中的主机,而不是在命令行输入凭据,更容易欺骗提示,如果您只是在最后一步重定向到localhost但是远程主机上的大多数逻辑这种方法还允许独立于客户端命令行应用程序部署授权流的更新,这具有重要的安全性好处。也就是说,基于Web的登录并不总是正确的方法。还有值得研究其他身份验证机制,例如libpam(在libpam下,你可以使用函数pam_authenticate来验证用户而不是服用密码直接输入)。值得投入一些研究来确定特定用例的最佳机制。


0
投票

在Linux和其他类似Unix的平台上,你可以使用termios.h。您需要禁用echo end规范模式进行输出,并在每个获得字符后打印*。有C代码示例:

#include <termios.h>

struct termios term;

/* Disable echo input characters and buffered input by disabling ICANON*/
static void disable_echo() {
    struct termios new;
    if (tcgetattr(fileno(stdin), &term) != 0) {
        perror("tcgetattr failed");
        exit(-1);
    }

    new = term;
    new.c_lflag &= ~ICANON;
    new.c_lflag &= ~ECHO;
    if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0) {
        perror("tcsetattr failed");
        exit(-1);
    }
}

/* Enable normal terminal state after getting password*/
static void enable_echo() {
    if (tcsetattr(fileno(stdin), TCSAFLUSH, &term) != 0) {
        perror("tcsetattr failed");
        exit(-1);
    }
}

/* Read password which will be printed as `*` characters */
static void mask_getstr(char* buf, size_t size){
    char c = '\0';
    while (--size > 0 && (c = getchar()) != '\n') {
        *buf++ = c;
        putchar('*');
    }
    *buf = '\0';
}

-1
投票
    #include<iostream.h>
    #include<stdio.h>
    #include<string.h>
    void main()
    {
     char str[10];
     int i=0,x,y;
     cout<<"enter : ";
     while(1)
      { str[i]=getch();
        if(str[i]==13)
        break;
        if(str[0]==127||str[0]==8)
        continue;
        if(str[i]==127||str[i]==8)
        {
           i--;
           x=wherex();
           y=wherey();
           gotoxy(x-1,y);
           clreol();
         }
         else
         {
           cout<<"*";
           i++;
         }
       }
     if(strcmp(str,"1234")==0)
     cout<<"Welcome";
     else
     cout<<"Try again";
    }
© www.soinside.com 2019 - 2024. All rights reserved.