我对编程很陌生-刚开始使用C ++。所以我想制作一个应用程序-只是为了好玩-用星号掩盖用户输入。我做了一些研究,发现了我想要的东西。正如您在下面的代码中看到的那样,它可以正常工作,但仅检查我输入的字符“ correct_password”的密码。我认为扩展选项会更具挑战性。该程序将写出两个选项:1.注册-仅输入您的登录名和密码(不带星号),然后将其存储到文件中(我猜是fstream); 2.登录-输入登录名和密码后(仅带星号的方式)它在getpass中)如果用户实际注册,它将检查文件中的数据。尽管我不知道如何进行,但甚至考虑过可能要加密该文件中的数据。好吧,学习一些新知识只是东西,我知道这不是真正的事情,编写这样的代码也没有真正的目的-只是弄乱C ++。也许您对如何解决这个问题有一些想法?在我写完这条星号之后,我真的看不到应该把其他选项放在哪里,存储在文件中等等。很想了解一些想法,并感谢经验丰富的编码人员的投入:)
我尝试在getpass中使用fstream,但是没有解决。通常,我想使用登录名和密码输入来扩展该程序,将它们存储到.txt文件中,然后程序将检查用户是否已注册,并且在使用此数据输入进行登录时将用星号掩盖-就像我的第一个想法一样该程序仅屏蔽密码输入。我真的不知道如何在getpass中使用该方法拆分未屏蔽的输入。
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
string getpass(const char *dat, bool s_asterisk=true)
{
const char BACKSPACE=8;
const char RETURN=13;
string password;
unsigned char ch=0;
cout << dat;
DWORD con_mode;
DWORD dwRead;
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode( hIn, &con_mode );
SetConsoleMode( hIn, con_mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT) );
while(ReadConsoleA( hIn, &ch, 1, &dwRead, NULL) && ch !=RETURN)
{
if(ch==BACKSPACE)
{
if(password.length()!=0)
{
if(s_asterisk)
cout <<"\b \b";
password.resize(password.length()-1);
}
}
else
{
password+=ch;
if(s_asterisk)
cout <<'*';
}
}
cout << endl;
return password;
}
int main()
{
const char *correct_password="fdsidfjsijdsf21128321873";
START:
string password=getpass("Enter the password: ",true);
if(password==correct_password){
cout <<"\nCorrect password."<<endl;
exit(1);
}else{
cout <<"\nIncorrect password. Try again.\n"<<endl;
goto START;
}
return 0;
}
答案 0 :(得分:3)
通常,您不想在文件中存储实际密码。尽管对它们进行加密会(至少在某种程度上)有助于提高安全性,但是通常仍然相当不安全,最好避免使用。
通常,您要做的是对密码加盐,然后用加密哈希对加盐的密码进行哈希处理。然后,您存储盐和哈希,而不是密码本身。
然后(对于最简单的情况),当用户想要登录时,重复相同的过程:检索盐作为其密码,将盐应用于输入的密码,对结果进行哈希处理,最后将结果与您存储的值。如果它们匹配,则假定用户输入了正确的密码。如果它们不匹配,您就会知道它们不匹配。
请注意,这仅对于用户本地(或至少通过安全连接)登录到您的应用程序是合理的。如果他们可能通过不安全的连接登录,则您还需要变得更加复杂。
不过还有一个要点:几乎所有这些事情都应该在外部 getpass
发生。 getpass
应该做的只是一件事:输入用户的密码。盐腌,散列,存储等都应与此分开进行。