2014-09-23 45 views
11

形式(*)輸入密碼,我想寫一個簡單的C程序,以確認password,例如,如果密碼等於的話,我想打印歡迎其他再試一次。但問題是:如何顯示在星號上的終端

我想顯示在*)的形式輸入密碼。 例如 ..如果用戶將輸入1234它將顯示爲****以避免其他人看到輸入的密碼。

任何人都可以給我一個想法如何使用C或C++來實現它。 平臺:UNIX

+2

你可以發表你寫的是什麼嗎? – SSC 2014-09-23 09:02:27

+4

Duplicate:http://stackoverflow.com/questions/17130979/how-to-have-password-echoed-as-asterisks-using-getch – 2014-09-23 09:07:17

+3

你需要指定你的平臺作爲解決方案,這是平臺特定的 – 2014-09-23 09:13:11

回答

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的工具將共享相同的瀏覽器會話),並允許您僅實現一次登錄流程,此方法還可以減輕網絡釣魚風險(用戶可以在瀏覽器中輸入憑據時明白地看到主機,而不是在命令行上輸入憑據,因爲欺騙提示非常容易,而且如果您只在最後一步重定向到本地主機,大多數遠程主機上的邏輯,這種方法也允許更新授權流程,而不必考慮具有重要安全優勢的客戶機命令行應用程序。也就是說,像這樣的基於web的登錄並不總是正確的方法。還有一個值得關注的替代驗證機制,比如libpam(在libpam下,您可以使用函數pam_authenticate來驗證使用情況而不是直接將密碼作爲輸入)。值得投入一些研究來確定您的特定用例的最佳機制。

+11

我很抱歉,但您是否建議OP從他的控制檯應用程序輸出一個驗證頁面的URL? – 2014-09-24 08:33:11

+0

@LightnessRacesinOrbit,是的,我做到了。是的,我知道這很奇怪,但是它是2014年的......即使你在終端上打字,你仍然可以訪問瀏覽器,這是正確和安全地實施委託登錄的唯一方法,你可以確保您的密碼(以及某些情況下的第二個因子令牌)僅限於身份提供者,而不是控制檯應用程序。 – 2014-09-29 08:24:53

+1

@MichaelAaronSafyan安全性或用戶體驗考慮因素已經超出了這個問題的範圍,在沒有更多上下文的情況下,您無法以合理的方式解決這些問題。我建議你刪除你答案的最後一段,在這種情況下這是毫無意義的。 – 2014-09-29 08:40:23

-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"; 
    } 
0

在Linux和其他一些類Unix平臺上,您可以使用termios.h來實現此目的。您需要禁用回聲結束規範模式輸出並打印每個字符後打印*。 有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'; 
}