1

I am in the process of developing a console application that acts as a Diary. At this stage I am developing the login authentication and have hit a bit of a wall! As I will be dealing with text files for both my login and diary storage, I would like to encrypt these text files from prying eyes.

Now, the problem is I do not know how to go about the decrypt >> check user&&pass >> encrypt again.

Would it be along these lines?:

  • Program Loads

  • Decrypt passwords.txt

  • If at any point the program closes, encryptFile() is ran.

  • Validate user entry

  • Encrypt passwords.txt

If I am along the right lines how do I go about implementing this? I searched for encryption tutorials for text files using c++ and they were not very helpful.

Here is my butchered beginner password.txt code, where shall I go from here? If there is an encryption tutorial/article you recommend that I missed please post it!

void checkPasswordFile() {

string username;
string password;
string passwordAgain;

string userIn;
string passIn;
string line;

ifstream passwordFile("passwords.txt");
istringstream instream;


if (passwordFile.good()) {


    cout << "\t==================================" << endl;
    cout << "\t----------------------------------" << endl;
    cout << "\tYou are a returning user, please fill in your details" << endl;




    while(!passwordFile.eof()) {
        getline(passwordFile, line);
        instream.clear();
        instream.str(line);
        username = line;

        getline(passwordFile, line);
        instream.clear();
        instream.str(line);
        password = line;
    }


    do {
        cout << "Username: " << endl;
        cin >> userIn;
        cout << "Password: " << endl;
        cin >> passIn;


        if (userIn == username && passIn == password) {

            displayMenu();

        } else {

            cout << "Username and Password Do Not Match, Try Again" << endl;
        }

    } while(userIn != username && passIn != password);


} else {
    cout << "file no exist";


    ofstream passwordFile;
    passwordFile.open ("passwords.txt", ios:: in | ios::app);

    cout << "\t==================================" << endl;
    cout << "\t----------------------------------" << endl;
    cout << "\tThis is your first run, please enter a username and password" << endl;
    cout << "\tUsername: " << endl;
    cin >> username;
    cout << "\tPassword: " << endl;
    cin >> password;

    /*
    Do Loop:
    Prompts Re-Entry if PasswordAgain is not equal to Password
    */
    do {

        cout << "Re-Type Password: ";
        cin >> passwordAgain;

        if(password != passwordAgain) {
            cout << "Passwords Do Not Match! Try Again" << endl;
        }
    } while(password != passwordAgain);


    passwordFile << username << "\n";
    passwordFile << password;
   }

}

Thank you very much for your time.

p.s for the life of me I cannot find out how to do:

Username:[cin>>username] on the same console line, sorry for doubling up but didn't deem it a big enough question for its own post! Thanks.

EDIT:

I have succesfully been able to decrypt the username and pass when created and stored in the text file. Then when the user comes back, what they entered is encrypted and compared with the file.

Problem being this only works for short words, user pass works, but username and password does not... any ideas why? Here is my encryption code:

 char encryptKey = 'h';
        cout << "\tUsername: ";
        cin >> userIn;
        cout << "\tPassword: ";
        cin >> passIn;

        for (int i = 0; i < userIn.size(); i++) {
            userIn[i] ^= encryptKey;
        }
        for (int x = 0; x < passIn.size(); x++) {
            passIn[x] ^= encryptKey;
        }

        if (userIn == username && passIn == password) {

            displayMenu();

        } else {

            cout << "\tUsername and Password Do Not Match, Try Again" << endl;
        }
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
speak
  • 5,202
  • 4
  • 36
  • 41
  • 1
    As a recommendation, it would be better if you never wrote the decrypted file to disk. – Wug Jul 12 '12 at 23:22
  • Presumably your binary needs to contain the encryption key(s), so your app won't really be _that_ secure for anyone who knows how to use a debugger and read asm. – ildjarn Jul 12 '12 at 23:25
  • I'm only in my first week of c++, this is a personal project to advance knowledge so I am fine with that, I just need the .txt file to be encrypted so users cannot just dip into the file outside of the program. – speak Jul 12 '12 at 23:29
  • You could encrypt the user supplied password and check it against the list of encrypted passwords and never decrypt anything. Thats not to say that someone couldn't generate a new password easily enough and add it to the passwords.txt file.. – Pete Jul 12 '12 at 23:29
  • @Pete : At that point, there's no point in encrypting the password at all -- hashing it would be more sensible. – ildjarn Jul 12 '12 at 23:31
  • 1
    also for doing the username on the same line as "username", drop the 'endl' from the cout << "username:" – Pete Jul 12 '12 at 23:33
  • This is really not what I am trying to get at, this is a first week c++ users project, nothing more. A simple encrypt, load, decrypt, validate, encrypt, end. Is what I am after. Thanks for the cout bit, appreciate it! – speak Jul 12 '12 at 23:34
  • 1
    just decrypt it into memory then. – Pete Jul 12 '12 at 23:35
  • 2
    but seriously just doing a hash of the supplied password and comparing with the hashed passwords in the file is far easier and probably more secure. – Pete Jul 12 '12 at 23:37
  • Thank you, what specifically should I be googling for? This is all very new to me and something I've never touched upon. if file doesnt exist: take user input, encrypt into hash. Then when the user comes back to login I take the userinput, hash it, compare to hash in text file and act upon it? – speak Jul 12 '12 at 23:39
  • 1
    Read this: http://crackstation.net/hashing-security.htm It's not specifically about C++ but it covers the concepts of hashing passwords. – Pete Fordham Jul 12 '12 at 23:58
  • I updated my original post, could anyone mind taking a look? It's an odd problem! – speak Jul 13 '12 at 00:16

1 Answers1

1

The right thing to is not to encrypt the passwords file - the issue is that the encryption key for the file would need to be stored somewhere that the program can access it, which would make it relatively easy to find and abuse.

Instead, you should be using password hashing (using a strong hash algorithm like SHA1). A hash algorithm is a algorithm that deterministically maps a piece of text onto a large number (called its hash), and is designed to be irreversible without great effort. The basic concept is that you take the password, use it to compute its hash, and then store that hash. Later, when the user enters the password to log in, you compute its hash again and compare the resulting hash to the stored hash. Even if someone gains access to the hashes, they do not obtain the password, which is important, because people often share passwords between applications. Don't implement your own SHA1 hash - see "What is the best encryption library in C/C++?" for a list of libraries.

You must also use salting and key stretching to defend against common brute force attacks.

Community
  • 1
  • 1
Chiara Coetzee
  • 4,201
  • 1
  • 24
  • 20
  • 1
    The system can still be relatively easily abused by someone who knows what they are doing - disassemble the code and extract the password hashing code. use this code to generate a hash of a password of your choosing, and modify the passwords.txt file to include this hash. You then know the password. – Pete Jul 13 '12 at 11:17
  • 1
    That's true - assuming we're talking here about a shared system, the passwords file should not be world writable. In UNIX this can be done by having the app invoke a setuid tool to update the passwords file (the tool requires the current password to update an entry), or communicate via IPC with an authentication service. It shouldn't be world-readable either, but hashing is defense in depth against the case where somehow it's exposed. – Chiara Coetzee Jul 13 '12 at 21:27