I am making a program in C that allows the user to register and login. When the user registers I want to save his username and password in a file.
As I understood it, the best way of doing so is adding a random salt to the end of the password and then store a secure hash (SHA-1 for example) of the salted password.
My question is: If I locally store the username, hash and salt in the text file, what prevents an attacker from just changing the hash and salt in the file to his own SHA-1 hash with his own salt and then log in using his new password?
Thanks.
2 Answers
It depends on whether the attacker has only access to this password file, or if he has access to the executable as well. In the latter case you can only make it harder to exchange the hashes, but you cannot entirely prevent it.
For the first case, on can use a HMAC to verify the stored hash:
- Your application would then contain a secret strong key, and would calculate the HMAC of the hash with this key.
- This HMAC can be stored together with the password hash in the file.
- When reading the hash for verification, the software calculates the HMAC again and can compare it with the stored one.
An attacker won't be able to produce the correct HMAC for his own hashes, as long as he doesn't know the secret key in your application. So what we gain is, that the password file cannot be altered but by your application, the security is concentrated into the key of your application. The same can be achieved with encrypting/decrypting the password file.
P.S. Please do not use SHA- to store passwords, instead use a hash function with a cost factor like BCrypt, PBKDF2 or SCrypt.*
It seems you have only one single server in place, which hosts the application, but also the username and hashed password. In this configuration, there is no perfect protection against an attacker being root.
However, you can try to have some good features:
- The hashed password makes it hard for an attacker to get the password and use the application with the user's credentials
- however, an attacker could indeed change the hash. To prevent that, you could try to protect that file, either by:
- detecting changes comparing with a remote copy
- or use a signature on it: basically, allowing only your application to update password. You can have a secret key in the app, used to sign the file, and add the signature at the end. When the app reads the file for authentication, it can check if the file was corrupted or not. It's probably going to be hard for the attacker to get that signature mechanism, but nothing impossible of course.