SHA-256 on the database side - database

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.

Related

Safely storing a password locally

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.

Is it beneficial to encrypt usernames stored in the database?

The first & accepted answer on this question about passwords management suggests to encrypt the user identifiers in DB.
The good point is that if anyone gets a password, he has to know how to decrypt the user login to get the full login/password pair.
Some disadvantages I see, for example:
you have to decrypt user logins every time you want to display them
if you want to do a 'begins with' search on user login to find users, you cannot simply use LIKE '...%'
ORDER BY on login field may be quite difficult too...
What would you recommend (encrypt user identifiers or not)?
As usual, the answer is "it depends".
In general, I'd say that if an attacker has access to your database, your security situation is so badly compromised that encrypting the passwords will likely do you no favours. This is different to using a one-way hash - it's likely that an attacker who has access to your database also has access to your decryption key, whereas one-way hashes, by definition, are one way.
As you already say, it's likely that you will need regular access to the userIDs (esp. if you use email addresses as user IDs); in that case, again, an attacker who can read your database likely can intercept the unencrypted data.
So, if you work for a bank, the government, or any other place where data security has to be at the very top of the list, this additional protection may just be worth it, especially if you have a strong key management system.
For other uses, I'd consider the additional security too small to merit the additional pain.
Encryption is considered to be a lesser form of secret storage than message digest functions. In fact, storing an encrypted password is a clear violation of CWE-257.
But why not hash the username? When the login the application will have the plain text. Depending on your application, you might not need to display a list of users. this would be an added layer of security, as both hashes have to be broken before the attacker can login.
That being said, if you have a plain text list of every username it will be trivial to perform a dictionary attack against any recovered hash. Further more user names are not created to be difficult to guess, often times users choose goofy names of birds or silly games like chess so that they are easy to remember.

Using a random salt in password encryption?

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.

Maintaining a secure database of user logins and info?

I want to have a login form on a charity website I am building (it's for a friend, and I'm learning on the go), and I want to know what languages/software should I learn to build databases for user logins and info? Note: it HAS to be secure and relatively simple to learn for someone with moderate programming experience.
Update: I understand that CMSs offer good tools for logins etc. but I want to do this all by myself.
The simplest thing you could do is hash and apply a salt to your passwords before entering them into the database. "The Wicked Flea" has a pretty good answer in another question here.
Have you thought about grabbing an off the shelf CMS? Most decent CMS's should contain all the functionality you need for a simple charity website. It would also give you a solid solution to your login form issue.
EDIT
As for what language to use. It really isn't very important so long as you are comfortable with it and willing to put time and effort. It shows in your profile that you're looking to learn PHP. Looks like writing a login form in PHP would be a nice starting point. As for a database back end. Again, it doesn't really matter. Just please just do not use MS Access. Most PHP developers (assuming) seem to use MySQL since it's usually what is included with a PHP web host.
About security, hashing and adding a salt to your password is about the easiest thing you can do. You could do something like this:
User clicks sign up link
Bring up sign up form using SSL
Once user clicks the submit button
Hash password. Add salt. Store in database. Adding a salt to your hashed password will prevent attacked from using a rainbow table to brute force your passwords. Take a look here for functions that take care of hashing passwords.
You could also force users to create a password with specific rules. Such as, requiring all passwords to be greater than 6 characters, at least one number, etc...
Once the user needs to log in, you can do something similar to:
Get username and sanitize it. Remember to NEVER trust the users input. It doesn't matter if God himself wants an account on your website.
Escape the password to ensure people without an account get access via SQL injection. You can do this using PHP's mysql_real_escape_string function.
Once all is in place you can query your database to see if there are any rows returned.
Lastly, never email your user their password in plain text. If the user forgets their password, simply allow them to create a new password. You can do this by sending the user a link in their email which will give them the ability to do so.
Honestly, your best bet is probably to complete this task and post back (new question) on SO with your code. From there we can analyze it and take it from there.
Something along those lines should fulfill your requirements.

Store Encrypted Username Hash in Database

I'm currently working on basic user authentication for an app I'm putting together, and I don't have much experience with security.
This said, I understand the practice (and necessity) of salting/storing a (salted) password hash in a database as a blob, as opposed to the password (encrypted or no). I've already implemented this.
Is there anything to be gained by salting/hashing a user name and storing the hash in the database, as opposed to the username in plain-text (or encrypted)? It strikes me this would make it quite a bit harder to determine which users may access the system using the database for authentication.
Since it's vital to make it difficult for someone to crack the password for a user account, wouldn't it also make sense to increase the difficulty for determining which users are viable?
Edit: it's possible some of the language I'm using isn't 100% correct: feel free to correct :-)
Edit2: I changed one of my first points to indicate salting hashes -- thanks everyone for pointing out that I missed this :-)
Edit3: Removed wording indicating I am encrypting/decrypting a password. I'm using salted hashes and am storing that in the DB -- thanks Scotty for pointing this out.
It depends on the context
It's important to assess the sensitivity of the material you're serving. To dig deeper, I'll provide a few use cases.
Scenario 1: A social networking application
All of your user's interactions happen in the public. Their email address will be used as their username. There username is not considered private because their name appears in all their posts. The username may be searched by other users and/or email invites are enabled.
Verdict - Hashing = Bad
Scenario 2: An E-Commerce site
The user may or may not participate in public interactions (ex. commenting, reviews). Using an email address as the username is probably a bad idea because, through the use of password recovery, a compromised email account means a compromised user account on your site.
There is a lot of gray area here that is typically exploited for 'convenience.' If your site uses email as the user name, stores shipping history, and credit card numbers; a compromised email could mean a lot of identity theft troubles for your user.
In this case, using a policy where the username is not the user's email address is probably a good idea. Hashing the email adds no value.
Note: I'm looking at you Amazon.com.
Verdict: Common Practice != good practice
Scenario 3: A porn site
Make the username a pseudonym and the login name the user's email address. They may feel inclined to talk about the content and don't necessarily want their name to show up on Google's results for a smut site.
Assume the worst here. If somehow your database is hacked, the exposing of your user's identities could cause irreparable harm. Don't think this could happen to you? Take a look at this article.
Not only are their user's accounts hacked and passwords exposed but, there's a good chance a lot of those users used the same password on their email accounts. Now their info is posted anonymously on PasteBin for the whole world to see. Even worse, most of them probably don't even know this has happened yet.
By simply hashing both the username and password, they would have saved themselves and their users a whole lot of trouble.
Verdict: Definitely hash the email address whether or not it's used as the username.
Scenario 4: A bank
It should go without saying that no expense should be spared when it comes to banking/financial sites.
Security can be increased by:
Using a username other than the email address
Forcing a unique username by requiring numbers and letters
Hashing passwords
Requiring 2-point authentication (in case the user's email password is compromised)
Hashing email addresses
etc...
No expense should be spared to protect your users because, to not do so, means you're gambling with their livelihood.
Conclusion:
There is no hard and fast rule for security that applies to all sites. In some cases, the username is made public so hashing it adds no value. In others, not hashing it could cause irreparable harm. If you do end up developing a site where a username/email hash could be made useful here's a good approach.
Hash the username
Generate a unique salt for the user
Hash the password using the salt
Store the password with the salt in the database
By not hashing the username with a salt you avoid the chicken/egg problem. Unless you use a static salt for all of the usernames.
Keep in mind that a static salt for all the user accounts may be found out by reading the code. Once a static salt is found out, it'll essentially be useless when a rainbow table attack is employed. If you salt the passwords, generate a dynamic salt and store it along with the rest of the user's credentials in the database.
If you want hard/fast rules for simplicity here are a few good assumptions to remember:
Assume your database may be compromised at some point
Assume your source code will be compromised at some point
Assume your user's email will be compromised at some point
Assume your user's are dumb and use the same password for your site as they use for their email
Assume that hackers are smart/resourceful and financially driven.
If you choose to store sensitive/private data, then going the extra step may save you a PR/legal nightmare in the future.
Update:An interesting article about seed hashing just showed up on Coding Horror.
Short answer: most likely no.
Long answer: Your situation seems to lack the key "my usernames are sensitive because of ..." which raises the question: "Why? What is the specific, demonstrable problem that protecting usernames would solve?"
Without that problem, what you are describing is a common pitfall in security-related development (and really development as a whole): coming up with some idea to secure or obfuscate some part of the system, and then searching for a reason to use it. As with anything in software development, you should avoid doing anything other than exactly what is needed until a clear problem presents itself that can only be solved by using a specific tool.
Extra hint (for free!): salt your password hashes. Plain-old hashes are far less secure.
If you salted & hashed the username, you'd leave yourself with a bit of a chicken & egg problem.
If you salted & hashed the username, how would you find it in the database? You'd need to look up the user's record to find the salt you used to hash the username...
Probably not. Think of it this way - the username is the application's way of figuring out which account a user is trying to login as. The password is the application's way of figuring out whether the user is actually allowed to login as that account. In practice, this means you're going to look up a row in your accounts table using the username as an index. By encrypting the username, you're simply making it harder to find the right row.
However, if you're using the same encryption scheme to encrypt the username and password, they are pretty much equally secure - if you can break one, you can break the other. Thus, encrypting both makes it harder to lookup the user, but doesn't add any additional security.
Note: In your question you talk about decrypting your password field. You probably want to make this impossible (literally). Most people encrypt their passwords using a one-way hash function of some sort (MD5 and SHA256 are popular), along with a salt. The "one-way" part simply means that once you run something through the function, you can't use what you get out to get what you started with. However, if you start with the same input, you'll always get the same output. The salt is a secret that only your application knows (sort of like an encryption key), which is added to whatever you are encrypting, before it is run through the one-way hash. This makes it impossible to do things like match two encrypted passwords from two different sites (assuming they're using different salts).
It's not very fair to your users to store their password in plain text since everybody that has access to your database can see their passwords. You should use a salted hash.
Salt_(cryptography)
You can never properly evaluate the security of a system by looking at a single part of it in isolation. Whereabouts are you storing the key to decrypt the passwords?
Do the people that have access to the database also have access to the location you are storing the encyption key? If so you've only gained a minor improvement in security by encrypting the passwords and probably nothing much more to gain by encrypting the usernames.
If the decryption key and program using it are more secure than the database - which is pretty unusual, normally the database is in the most secure spot possible - then there would possibly be additional benefit to also encrypting the username as you'd be depriving attackers of useful information in brute force attacks.

Resources