C++ simple password-protected console app I have been reading about passwords and hashing algorithms and what not and decided to write a program.

Overview: The user should be prompted to create a password the first time the program is executed. They should enter a key and confirm it. If they have executed the program previously, then they should just enter the password to gain access.

I determine if the user has run the program by checking if key.txt exists. Is there a more preferred method?

I tried to streamline some code with the two bool functions. Any other suggestions for cleaner or more concise code?

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include "sha256.h"
using namespace std;

bool keyExists() {
    bool keyExists = false;
    ifstream inFile("key.txt");

    if (inFile) {
        keyExists = true;
    }

    return keyExists;
}

bool isMatch(string key, string confirmKey) {

    bool match = false;
    if (key == confirmKey) {
        match = true;
    }

    return match;
}

int main() {

    if (keyExists()) {
        string key;
        string storedKey;
        cout &lt;&lt; "Please enter key: ";
        getline(cin, key);

        SHA256 sha256;
        ifstream inFile("key.txt");
        getline(inFile, storedKey);

        if (isMatch(sha256(key), storedKey)) {
            cout &lt;&lt; "Acces Granted!\n";
        }
        else {
            cout &lt;&lt; "Access Denied!\n";
        }
    }

    else {
        string key;
        string confirmKey;

        cout &lt;&lt; "Please create a key: ";
        getline(cin, key);
        cout &lt;&lt; "Confirm key: ";
        getline(cin, confirmKey);

        if (isMatch(key, confirmKey)) {

            SHA256 sha256;
            ofstream outFile("key.txt");
            outFile &lt;&lt; sha256(key);
        }

        else {
            cout &lt;&lt; "Keys do not match!\n";
        }
    }

    return 0;
}


Many thanks to Stephan Brumme for the awesome hashing algorithm code! This was very easy to implement.
Using namespace std isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing with std::, you'll get used to it in no time.
Your function keyExists can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. So is_first_use, or is_first_visit as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:


Original version

bool keyExists() {
    bool keyExists = false; // the homonymy is a bad idea
    ifstream inFile("key.txt");

    if (inFile) { 
        keyExists = true; // 
    }

    return keyExists;
}


first trimming

bool keyExists() {
    bool keyExists = false;
    ifstream inFile("key.txt");

    keyExists = inFile; // because streams can be converted to bool as you know

    return keyExists;
}


second trimming

bool keyExists() {
    ifstream inFile("key.txt");
    return inFile; // you specified the return type, so the conversion will occur
}


third trimming

bool keyExists() {
    return ifstream("key.txt"); // no need for a named object
}


So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.


Your function isMatch suffers from the same issue. 


original version

bool isMatch(string key, string confirmKey) {

    bool match = false;
    if (key == confirmKey) {
        match = true;
    }

    return match;
}


suggested implementation

bool isMatch(const string&amp; key, const string&amp; confirmKey) { // pass it by reference to avoid a potentially costly copy
    return key == confirmKey; // no need to store that in a `bool` before returning it
}


Then again I'm not sure it needs a function of its own...    


What's a valid key?


It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?