使用外部 txt 文件验证密码无效

Authentication for password not working using an external txt file

我的外部文本文件,包含以下形式的用户名和密码:

username1
password1
username2
password2

出于某种原因,它没有将输入的密码与文件中的密码进行比较。这是代码:

    userdata.open("userdata.txt");
    while(getline(userdata, temp))
    {
        counter++;
        if(counter % 2 == 1)
        {
            usernames.push_back(temp);
        }
    }
    cout<<"Please enter your username: ";
    cin>>username;
    for(int i = 0; i < usernames.size(); i++)
    {
        if(username == usernames[i])
        {
            usernameMatch = true;
            break;
        }
    }
    while(usernameMatch == false)
    {
        cout<<"\nInvalid Login! Please re-input your username: ";
        cin>>username;
        for(int i = 0; i < usernames.size(); i++)
        {
            if(username == usernames[i])
            {
                usernameMatch = true;
                break;
            }
        }
    }
    while(getline(userdata, temp))
    {
        counter++;
        if(counter % 2 == 0)
        {
            passwords.push_back(temp);
        }
    }
    cout<<"\nPlease enter your password: ";
    cin>>password;
    for(int i = 0; i < passwords.size(); i++)
    {
        if(password == passwords[i])
        {
            passwordMatch = true;
            break;
        }
    }
    while(passwordMatch == false)
    {
        cout<<"\nInvalid Login! Please re-input your password: ";
        cin>>password;
        for(int i = 0; i < passwords.size(); i++)
        {
            if(password == passwords[i])
            {
                passwordMatch = true;
                break;
            }
        }
    }
    cout<<"\nLogin Successful!"<<endl;
        userdata.close();

用户名检查器有效,但密码检查器部分不起作用,当我输入正确的密码时,它只会继续返回“Invalid Login! Please re-input your password:”。

我是新来的所以如果我遗漏了什么请告诉我。此外,我只能使用包含的库,因为除了 ctype.h

之外我们没有学到任何其他库

很遗憾,我们没有所有相关代码。根据您提供的内容,我假设 tempusernamepassword 都是 string,并且 usernamespasswordsvector<string>.

第一个潜在问题

首先检查您是否已明确初始化 counter=0。如果您忘记了初始化,那就是一场随机赌博。

那么,如果你的 username 或你的 password 可以包含 space,你的 cin>>xxx 将不在同步,因为它会将此视为两个不同的输入。因此,如果规则是每行一个条目,请使用 getline(cin, xxx)

阅读

您阅读文件的方式存在严重问题

您打算先读取您的 while 文件以过滤掉奇数行的用户名,然后您再次读取该文件以过滤掉偶数行的密码。但是:

  • 您的 while 循环退出时出现错误 userdata:无论您做什么,您都无法读取任何内容,直到 userdata.clear() 错误
  • 无论如何,你永远不会倒回你的文件倒回。所以 getline 即使在清除错误后也会失败,因为你仍然位于文件的末尾。所以你需要 userdata.seekg(0); 才能倒带。
  • 最后,您永远不会将计数器重置为 0。因此,如果文件的行数为奇数(最后的空行足以导致这种情况发生),您的 odd/even 检查将失败。

一种更简单的方法是一次读取文件而不倒带:

while(getline(userdata, temp))
{
    counter++;
    if(counter % 2 == 1)    // if odd 
    {
        usernames.push_back(temp);
    }
    else                    // if even
    {
        passwords.push_back(temp);
    } 
}

最后,一个安全漏洞:-)

首先,您检查其中一个用户是否与用户名匹配。行。然后你检查密码是否匹配a密码,文件中的any密码,不一定是用户名对应的密码:

  • 这意味着合法用户可以在不知道密码的情况下冒充系统的任何其他用户!!
  • 更糟糕的是:如果任何用户使用弱密码,整个系统都可能受到威胁!!!

正确的方法是找到用户,保留其索引(这意味着 i 应该在循环外定义),输入密码后,如果密码与 [=54 处的密码匹配,则 cjeck =]相同索引.

现在,在询问密码之前询问用户名并告知用户名不匹配,这对黑客来说很有效,因为可以立即清楚哪些数据是错误的。

进行此检查的正确方法是询问用户名和密码,然后进行验证并仅告知登录无效(因此潜在的入侵者不知道是用户名还是密码或两者都是这是错误的):

cout<<"Please enter your username: ";
getline(cin,username);
cout<<"\nPlease enter your password: ";
getline(cin,password);
for(int i = 0; i < usernames.size(); i++)
{
    if(username == usernames[i])
    {
        usernameMatch = true;
        passwordMatch = (password == passwords[i]);
        break;
    }
}
while (!usernameMatch || !passwordMatch) 
...