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.
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.
Related
I'm making a mobile app for tv series. Basically like a tracker, to know what episodes to watch and when. And I wanted to store the information like episodes watched, user shows on a database. (the info about shows I get from a rest api)
So the thing is I don't find the need to have a server here, I just don't know what it should do.
And the problem is I'd like to make the database secure. And from what I've read the best practice is to create a salt using a cryptographically strong random number generator and prepend it to the password and then hash the whole thing using a hash algorithm, for example the SHA-256.
Then I store a hashed password and the salt in the database, and when I want to check if the password is correct, just hash it again and compare to the one in database.
So I have a special class in Java that can create such a salt, and all I needed to know is where and how to hash the whole thing. And what is what I'm asking about. I would not like to create a server that would just hash passwords.
Also another thing is how to go about implementing auto-login, which I also wanted to add once I figured this out.
I hope it's clearer now what I want to accomplish here.
Sounds like you're building a mobile app that stands alone, ie doesn't talk to a server.
You want the app to be password protected (even if their phone already is), and you want to store this password hashed, so that the pwd cannot be recovered on say a lost then rooted phone.
SHA256 is a fine hash but what you want is a real slow hash. Use bcrypt, PBKDF2, or scrypt.
The salt is not a secret.
When the user creates their account, create the salt, hash the pwd with the salt and store the password and salt somewhere. Each time the user logs in, get the salt, hash the password the same as before, and compare to saved password. If same, user authenticates.
You don't need to store the pwd in sqlite. It's probably easier just to store it in a text file.
I'm working on adding the option to encrypt uploaded files on my website by giving each file a "password", but I'm not sure of the best way to keep track of the encryption keys for each individual file. For example, when retrieving the file if the user enters the wrong password I'm pretty sure it'll download the file, but it won't be unencrypted properly. Is it best to store the hashed & salted passwords for each file in a database and match up there first? Or is there a better way to do it?
If you store the encryption keys as hashed (and salted) values, there is no way to retrieve the original encryption key. If you hash something (with a strong hashing algorithm), you cannot get the original back.
The best mechanism depends on the operating environment (OS, plus potentially other software installed), and on the requirements.
Depending on the specific requirements, it may be best not to store the encryption key at all. The point is that the user wants to protect data and the user knows the key. If it is possible to perform the encryption on the client side, the key would never have to traverse the network at all (e.g. encrypt in JavaScript). If the encryption must happen on the server, ensure the key is sent via an https connection, use it in memory to encrypt the file, and remove from memory (if your language supports immediately removing something from memory... e.g. in C# use a SecureString).
If you must keep the encryption key (which is a security issue on several levels), you will have to state more information about the operating environment.
I know this topic has been discussed a million times. But it's new to me and the more I read about it the less I understand what's actually happening or supposed to happen.
I add a per-user salt to the hashed storage of a user's password, so the stored password hash looks like this: hash(password + perusersalt).
This results in same passwords of different users being stored as different strings in the DB. Cool. But I'm not worried about someone breaking into the DB and looking up the hashed passwords. I'm worried about someone brute-force-querying my server for combinations of username and password. In this case the salted and hashed storage of passwords is useless, because the correct combination of username and password will yield a successful login. Right?
Am I correct under the impression that in this scenario the salt is pretty useless? Because the server only accepts username and password at the interface (no salt transmitted), a normal dictionary attack will do, right?
So the salt is only there to obfuscate the password of a user (obtainable only by reverse Rainbow Table lookup) from someone who has access to the DB. Hmm.
Related: My web app doesn't even transmit plain passwords. Passwords are already hashed client side, only to entirely reject responsibility about someone's stolen passwords, and the whole thing uses SSL.
Does this mean I'm more or less at the highest possible security level, because correct combinations of username and password must of course yield a successful login?
Thank you for clearing up the mess in my head.
You are correct in your assumption about the brute force attack. If the user has a simple password, the salt and hash won't really matter. The dictionary attack will guess "password" and allow the attacker in. You have to require a secure password from the user, then do the one-way encryption (hash it with the salt), and use SSL like you are.
"Passwords are […] hashed client side […] to […] reject responsibility about someone's stolen passwords, and the whole thing uses SSL."
Does the client send hash(password+salt) ?
With this design, a client does not really need the password in order to login successfully, it only needs the hash. So you might still be responsible for leaking the real password (the hash).
I've seen a few other threads about this topic, but I can't seem to find a few answers to some questions involving the use of a random salt in password encryption. To my understanding, the steps go something like this:
Generate a random salt for the user.
Append the salt to their password.
Use something like SHA-2 to hash the result.
Store both the salt and hashed password in the database.
How does this method work when retrieving the user's password and verifying log-in? One response says that the user's salt should be retrieved, appended to their inputted password, hashed, and then compared to the stored hash, but doesn't this raise some issues? Namely:
How do you retrieve the salt without compromising that user? If someone wanted to brute-force a certain account's password, wouldn't they be able to retrieve the salt that was sent back from the server to hash the inputted password, thereby eliminating the security that having a salt adds?
If we avoid the previous problem by doing the salt retrieval server-side, then won't we be sending the user's inputted password unencrypted at one point or another (so that it may later be appended to the retrieved salt)?
The salt should never be exposed outside of the service - your instinct is right that this would be exposing the salt and introducing risk.
Any communication between your client and server should occur over an SSL connection - or at least using some kind of encryption of the interaction.
Keep in mind the purpose of the salt: to make it harder for someone to precalculate hash codes and therefore be able to look up passwords in the case of the database being compromised. An 8 bit salt makes the hash space 256 times bigger, making precalculation that much harder. The salt isn't about securing communication - there are other solutions for that.
You have to use random salt because of goal of using it is protecting against some types of attacks such as dictionary attack, brute-force attack and rainbow attack. thus it's so important to generate random salt for each password and store hashed password and salt in user table or attached to user profile. When you want to validate user password it's enough to hash entered password with stored salt and compare with stored hash value. I don't believe #cherouvim advise because it seems he doesn't care about above attacks. For more information i suggest an amazing, simple and understandable article by Defuse Security
Good luck.
I use a fixed salt (for all passwords) which is hardcoded on the application code. Assuming that the salt cannot be exposed (e.g via the UI of the application) this looks simple and good enough.
The only way to not send an unencrypted value which can be used to log in is to use SSL. If the hash gets sent to the server, the hash itself can be sniffed and used to log in. Do it server side.
+1 to what ruslik said about the salt. It prevents dictionary/rainbow attacks. A rainbow table for an average password + several bytes of random binary data would be astronomically huge.
Security introduced by salt is that you obtain hash for something much bigger and non-standard than the plain password. It doesn't matter if its algorithm is closed, because it protects the hash stored in plain in database from rainbow or dictionary attacks.
It's also reccomended to take hash several times recursively, maybe readding the salt at each iterations, so that brute force will take much longer.
EDIT: to what Bevan said about communication: usually the "number used once" (NONCE) scheme is used to transmit passwords over unsecure channels. The server gives a random string never used before to the client, he appends it to the plain password, computes hash, and sends it. This protects you from eavesdropping attacks.
Hashing passwords protects against plainly visible passwords, and salting them guards against dictionary attacks. As far as protecting passwords during transport, I would recommend SSL/TLS.
I need a login system to check the user password.
I know about salting passwords, but should I store the salt and the encrypted password or should I only store the encrypted password and the salt is somewhere in my app config file?
Please pro and cons if there are some, thanks!
It depends on how you are using salts for encryption...
If the salt does not change frequently:
I would store the salt alongside the master key in a safe location. Storing it alongside each password would just constitute in a lot of redundant data. Furthermore the database is probably not as safe a place as the storage location of the master key. Mind that the salt may be an essential part of the password security. (Depending on lenght and strenght of passwords chose by the users...)
If the salt changes frequently, i.e. with every encrypted password:
In this case you would need to store a huge number of salts. As one salt is only useful for the decryption of one password it's not as critical a piece of information as in the above example, storing it in the DB alongside the passwords is ok I guess. At any rate, storing the salts in a the app config could get messy. (Unless you would create an special salt database or something like that.)
If you have differing salt for every password then you will have to store the salt and hashed password in DB itself. If you are using only one salt for all passwords, then you can prefer to store them in other location kind of config file.