c
2015-05-14 56 views 0 likes 
0

我必須提示用戶輸入密碼,所以當輸入密碼時我希望字符被屏蔽,我已經創建了代碼,屏蔽字符直到按下Enter鍵。但是字符數組pwd不會讀取我猜的字符!掃描時屏蔽文本 - C

char pwd[10]; 
while(ch!=13) 
{ 
    pwd[i] = ch; 
    ch = '*' ; 
    printf("%c",ch); 
    ch=getch(); 
    i++; 
} 
pwd[i]='\0'; 
printf("%s",pwd); 

當我嘗試打印密碼時沒有打印任何內容。

+2

這是os和終端依賴器。咒語庫unix –

+1

'我'初始化了什麼地方? –

+1

自己讀取密碼可能會造成安全漏洞。您可能會考慮使用操作系統服務(Linux上的PAM以及Windows提供的任何服務)。這有很多額外的優勢,如使用自動替代認證等。 – Olaf

回答

0

As @Olaf and @EugeneSh。提到,這是做密碼的一種可怕的方式。這就是說,這裏有一些幫助。

假設我正在初始化某處,將「pwd [i] = ch」移動到循環結尾,但在「i ++」之前。整個事情應該看起來像這樣(請注意,這仍然是非常錯誤的):

char pwd[10]; 
while(ch!=13) 
{ 
    ch = '*' ; 
    printf("%c",ch); 
    ch=getch(); 
    pwd[i] = ch; 
    i++; 
} 
pwd[i]='\0'; 
printf("%s",pwd); 

我實際上可能只有在用戶輸入他們的字符後纔打印「*」。讓我們來解決其他問題。

int i = 0; /* Since you didn't specify if this was initialized */ 
char pwd[15]; /* Setting this to 10 would have caused you to overrun your 
       buffer. Not only is that crashy, it's a also a HUGE 
       source of security holes. Let's not do that. */ 
/* Unless you're waiting for a user to enter in a 
    character which happens to be ASCII 13, you'll 
    never get out. Let's just change that to i since 
    I'm guessing you want a 13 character password. */ 
while(i != 13) 
{ 
    char ch=getch(); 
    pwd[i++] = ch; /* You can post increment right here so you don't 
        have to do it at the end of the loop where you 
        might forget */ 
    printf("*"); 
    fflush(stdout); /* Since we are using printf to a stdout (not 
         stderr, we need to manually flush stdout or 
         things won't show up until a newline is 
         eventually printed. */ 
} 
printf("\n"); /* Print a newline so we don't end up printing the 
       password on the same line */ 

pwd[14]='\0'; 
printf("Password entered into our crappy security system: %s",pwd); 
+0

問題是終端特定的(無論是tui還是gui) –

+3

實際上應該禁止打印任何密碼標記。這起源於Windows(沒有緩存); Unix/Linux沒有迴應任何東西,所以甚至無法從輸出的符號數中猜出密碼的長度。令人遺憾的是,Linux/Unix桌面採用了這種missbehaviour(對於KDE,至少它可以被禁用)。 – Olaf

+0

代碼包含緩衝區溢出,不能由EOF和/或CR終止。 – Olaf

1
#define MAX_PW_LENGTH 12 

char pwd[MAX_PW_LENGTH + 1]; 

/** Get Password 
* 
* \return True on success, false on failure (EOF, too long). 
*/ 
bool getPwd(void) 
{ 
    size_t idx; 
    char ch; 
    for (idx = 0 ; idx < sizeof(pwd) - 1 ; idx++) { 
     ch = getchar(); 
     if ((ch == EOF) || (ch == '\n') || (ch == '\r')) 
      break; 
     pwd[i] = ch; 
    } 
    pwd[i] = `\0`; 
    return (ch == `\r`) || (ch == '\n'); // might depend on OS what return-key yields 
} 

注意我用getchar作爲殘培是非標準和(IIRC)不會等待輸入,而是立即返回(非阻塞)。哦,我實際上do不輸出任何東西,因爲getchar需要整行輸入第一個(緩衝 - 見下文)。問題是:控制檯默認輸入字符作爲輸入(另見:見下文)。所以,你需要非回聲輸入;其餘的將會很好。

好的,我試圖提供一個簡單的解決方案。但是,至少對於Linux而言,默認情況下,getchar()有兩個主要缺點:終端默認回顯所有輸入,因此鍵入時顯示密碼。其次,它在輸入行在getchar()中返回char-by-char之前緩衝輸入行。

第一個顯然是一個殺手 - 反特徵,而第二個只禁止迴響星星或類似的東西(我反而勸阻)。但是,使用termios可以禁用控制檯的兩個功能;只是谷歌這一點。

另一種方法是使用提供getch()和一個簡單的'noecho()'調用來禁用此行爲(和cbreak()來禁用緩衝)的ncurses。但是,這似乎需要使用TUI功能,並且不能像普通的控制檯輸入一樣使用(但仍比termios更簡單)。

結論:使用系統的功能獲取密碼/認證。彷彿沒有這已經知道:-)

這裏是一個ncurses的版本:

#include <ncurses.h> 

bool getPwd(void) 
{ 
    // this should be done in main() or so only once 
     initscr(); noecho(); cbreak(); 

    size_t idx; 
    char ch; 
    for (idx = 0 ; idx < sizeof(pwd) - 1 ; idx++) { 

     // wait for input 
     while (ERR == (ch = getch())) ; 
     if (ch == '\n') 
      break; 
       addch('*');  // this should actually be disabled 
     pwd[i] = ch; 
    } 
    pwd[i] = `\0`; 
    return ch == '\n'; // might depend on OS what return-key yields 
} 
} 

結案。

+0

好,你的更好。我試圖讓我儘可能地和OP一樣,幫助他理解發生了什麼。但當然,去看看我:) – rost0031

+1

@ rost0031:仍然有問題(愚蠢的我!):這隻能正常工作,沒有輸出作爲getchar仍然需要EOF /返回,並不返回每個字符輸入。試圖現在使用getch(),但這需要(n)詛咒,我無法獲得它的鏈接。有趣的是,從未在Linux上編程C;只是在Linux上的嵌入式和Python上。可能必須打開我的第一個問題。諷刺? :-)) – Olaf

+0

說到諷刺,你之前說過的所有額外的修改是什麼......? – rost0031

相關問題