Win a copy of Transfer Learning for Natural Language Processing (MEAP) this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Paul Clapham
  • Devaka Cooray
  • Bear Bibeault
Sheriffs:
  • Junilu Lacar
  • Knute Snortum
  • Liutauras Vilda
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Piet Souris
Bartenders:
  • salvin francis
  • Carey Brown
  • Frits Walraven

what's the best way to handle password in web app?

 
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a web app with spring framework + jdbc that has user registration page. When the user creates an account, what's the best practice to handle the password? Should I store it directly on a database? I heard you may encrypt or "add salt" in password but does not know which is the best practice or api to use for security purposes... Can someone please share their ideas.. TIA
 
Rancher
Posts: 4540
47
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hashed with salt.
Not encrypted.
 
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't ever store the password as-is in plain text. One option would be to use a key derivation function like PBKDF2 to create a hash value of the password combined with a securely generated per-user salt value and store that. I wouldn't recommend developing a security layer that handles stuff like this yourself, though. It'd probably be better if you used a framework like Apache Shiro to handle this sort of thing.
 
Sheriff
Posts: 15506
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:Hashed with salt.
Not encrypted.


Certainly, 007

See also http://www.darkreading.com/safely-storing-user-passwords-hashing-vs-encrypting/a/d-id/1269374
 
Junilu Lacar
Sheriff
Posts: 15506
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are, of course, situations where you have to use encryption with passwords. For example, many applications connect to the database as a generic user and you don't want to put that user's password in plain text in a properties file or some other configuration file. Since there is no actual user to type in a password to hash and compare, you need to encrypt/decrypt the password in this case. I have used Jasypt to facilitate this.
 
Ranch Hand
Posts: 789
Python C++ Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bcrypt is the safest thing to use. You shouldn't roll your own.
 
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Never ever store passwords as a plain text! The two main reasons are:
1. If your database gets cracked, all passwords of your users are stolen. Many people use the same password for many websites, thus stealing a password from your database can allow to access many other accounts of given user.
2. You (and possibly co-workers) will be able to see users passwords. This is unethical. User password is his private thing and you (and anybody) shouldn't have access to it.

Encrypted password is also not the solution. Encryption keys can be cracked (or stolen) and in result the passwords can be read as well.

Hashing is the right way to do this. It's one-way algorithm that does not allow to "decrypt" a password, because password information is not stored. A hash is a result of mathematical transformations performed on input data (in this case, on a password). One set of data has only one hash, thus only one password has only one hash representation.

A hash cannot be transformed back to the password. Thus to verify user password you have to hash user input and compare it with the hash in the database. If a match is made, then the correct password is provided (as one password has only one hash).

I have said that a hash cannot be used to extract a password from it. Sadly, it does not mean that hashes are ultimate protection. An attacker, after obtaining a hashed password, can guess what input data (password) was used to generate that hash. He can start with hashing guessed passwords "a", then "b", "c",... "aa", "ab", "ac"... "ba"... and so on, until he or she gets a matching hash. This kind of attack is called "bruteforce" and is executed by automated software that generates extreme numbers of hashes per second. The attacker can also use a "dictionary attack", where he or she hashes words from a dictionary, or from list of most commonly used passwords. If a user used not an abstract password (like Am48$ma;a9) but a dictionary password (like "secret"), this method can obtain the right password very fast.

The longer password is, the longer cracking time will be. However, crackers are smart and have a thing called "rainbow tables". A rainbow table is a database of already computed hashes of various input data. If a user password is not long and complicated enough, there is a high possibility that his or her password is already computed in a rainbow table, and can be cracked in a matter of seconds.

To increase your security against rainbow tables, you use salts. A salt is a random data inserted to input data of a hashing function. This way an attack difficulty is greatly increased. Instead of performing a check against the rainbow tables of the entire database of passwords, the attacker has to brute-force every single user separately (provided that every user has unique salt). This method greatly extends the time required to crack a password.

Thus saying, salted hashes is the way to store your users password. But it's not everything. You said that you have a web app. The login and registration page must use a secure connection (over HTTPS). If you use unencrypted connection on those pages, they will be sent over network as a plain text. Those passwords can be easily stolen if somebody is sniffing traffic between user and the web server.

The final answer is: make sure your login and registration pages use https, and store passwords as salted hashes with unique salt for every user.

For further information I can recommend this link, it provides great information about the topic and even a Java class with implemented common hashing functions: https://crackstation.net/hashing-security.htm

Somebody also mentioned that you should not write your own hash function. The reason behind this is that the well-known hashing functions are written by professionals in this topic, and they were reviewed by many other professionals. Those functions are used very widely and their implementations are open. When thousands of eyes do not see any problems with given hash function, it means something. Some functions are being in used for long years, and the test of time for a hashing or encryption algorithm proves it's security.

One last tip: Many old articles and tutorials on Internet commonly use MD5 for hashing passwords. This hashing function is already cracked and is considered to be useless. Under any circumstances, do not use MD5!
 
Sheriff
Posts: 21919
106
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Adam Scheller wrote:Hashing is the right way to do this. It's one-way algorithm that does not allow to "decrypt" a password, because password information is not stored. A hash is a result of mathematical transformations performed on input data (in this case, on a password). One set of data has only one hash, thus only one password has only one hash representation.

A hash cannot be transformed back to the password. Thus to verify user password you have to hash user input and compare it with the hash in the database. If a match is made, then the correct password is provided (as one password has only one hash).


Not necessarily true. For instance, in PHP, the password_hash function generates a new value every time. That's why you can't simply hash the password to check and compare that, but you have to use password_verify to validate the value instead. As far as I know, the same is true for BCrypt. In other words, one password has many, many hashes. This provides extra security, as crackers can't just try to pre-generate a lot of hashes and try these.

One last tip: Many old articles and tutorials on Internet commonly use MD5 for hashing passwords. This hashing function is already cracked and is considered to be useless. Under any circumstances, do not use MD5!


I definitely agree, but it's not just limited to MD5; SHA1 and SHA256 are also quite insecure for password hashing. I'd definitely use something like BCrypt.
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:

Adam Scheller wrote:(...) One set of data has only one hash, thus only one password has only one hash representation. (...)



Not necessarily true. For instance, in PHP, the password_hash function generates a new value every time. That's why you can't simply hash the password to check and compare that, but you have to use password_verify to validate the value instead. As far as I know, the same is true for BCrypt. In other words, one password has many, many hashes. This provides extra security, as crackers can't just try to pre-generate a lot of hashes and try these.



password_hash generates different values because it automatically adds the salt. The generated hash contains additionally the used algorithm, cost and salt.

From it's documentation:


Return Values

Returns the hashed password, or FALSE on failure.

The used algorithm, cost and salt are returned as part of the hash. Therefore, all information that's needed to verify the hash is included in it. This allows the password_verify() function to verify the hash without needing separate storage for the salt or algorithm information.



Take a look at what happens when you provide salt manually: http://ideone.com/K4Uzak

Rob Spoor wrote:In other words, one password has many, many hashes. This provides extra security, as crackers can't just try to pre-generate a lot of hashes and try these.


This is wrong, and it misses the entire point behind hashes. Actually, if one password could have many hashes, it would simplify the cracking exactly "many" times.

One set of data can has only one hash, and this is the entire idea behind hashing. Thanks to hashing we can verify two sets of data to see if they are the same. If the same set of data could have different hashes, how would you compare them?

About the hash uniqueness, it's not exactly unique. Every hashing function has it's own collision probability. For SHA256, the probability of collision on one billion messages is equal to 4.3*10^(-60). Such probability is so low that it can be ignored.
 
Rob Spoor
Sheriff
Posts: 21919
106
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wasn't aware that BCrypt and password_hash add their own salts. They apparently return the salt as part of the hash as well, otherwise it's impossible to verify the hash.

So is it more secure to use your own salt, which can be somewhat hidden from crackers, or use a generated salt which is part of the hash? Does making the salt public add more or less security?
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
password_hash stores the salt at the beginning of the "right" hash, take a look on the results from the earlier mentioned code:
$2y$10$abcdefghijklmnopqrstuuqflPDzB6gcMhKa1rZqKiun2YGL5sa2u

A salt can be public and honestly I never saw any "hidden" salt. In databases, in very most cases, it is stored either in a similar form to what password_hash generates (in a single column), or as a hash and it's salt separately (in two columns).
It's not about salt being secret, it's about having unique salt for every hashed data. The idea of salts is to make rainbow attacks much harder and to prevent bruteforcing entire database of hashes at once. With unique salt for every hash in the database, the attacker has to bruteforce every password separately, thus making cracking much much longer operation. This is what salts are for.
 
Winston Liek
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks for your responses I learned alot..

Based of what I understand, I need to use https for login page, unique salt added per password before hashing.... But where should I store the salt value? Isn't it the salt becomes useless if I will store it in the same database? If the hacker gets access to the database containing hashed passwords, for sure he can access the whole tables in the database and will be easily track the salt columns.

And also, if I use one salt per web app (not per password), is it possible for hackers to access my deployed web app in the server?
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Winston Liek wrote:But where should I store the salt value? Isn't it the salt becomes useless if I will store it in the same database? If the hacker gets access to the database containing hashed passwords, for sure he can access the whole tables in the database and will be easily track the salt columns.


That question was answered at the bottom of the article that Junilu posted a link to, where someone asked the exact same question. You can safely store the salt in the database. It doesn't matter that a hacker gets the salt - it will still prevent them from performing certain kinds of attacks. See the answer by MichaelCoates there.

Winston Liek wrote:And also, if I use one salt per web app (not per password), is it possible for hackers to access my deployed web app in the server?


You should really use a separate salt per password, and not one salt for the whole webapp. Otherwise a hacker could generate a table with hashes of common passwords using the one salt that your webapp uses (if he knows the salt), and then he could still find accounts that use one of the common passwords. It would be considerably less secure than having a different salt per password.
 
Saloon Keeper
Posts: 21944
149
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just to add my $0.02. The headlines these days are rife with reports of major businesses and government entitites which have suffered intrusions that would allow the attackers to suck down passwords by the barrelful. So you definitely want to make those passwords as useless as possible outside of their proper context. Using one-way encryption is a major stab in that direction, and so much the better if the security systems in question blend in additional context that would be unavailable to external exploiters even after they'd cloned the company's entire set of production databases. Think multi-factor identification.

Speaking of security systems, a secure storage of password information is just one part of a secure environment. If you're using a do-it-yourself, locally-invented login/authorization system, it doesn't matter HOW secure your passwords are, because in my experience, over 90% of all the DIY systems contain major holes that even technically inept people can walk right through. In 15 minutes or less.

So unless you've a full-time, mathematically-trained security programming staff in your corporate assets, don't get clever and use a DIY login or some sample "login servlet" out of a J2EE textbook. Use the J2EE-standard security system and/or a well-respected third-party security framework like the one for Spring. Because the people who designed those frameworks were working full-time on security and ONLY security, not "and by the way, make sure this is a secure app". or "You're the tech systems group. whip us up a corporate standard". As a result, these are time-tested, well-documented frameworks done by properly paranoid people and designed to integrate smoothly into standard webapps.
 
author & internet detective
Posts: 39957
804
Eclipse IDE VI Editor Java
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also, don't e-mail people their passwords. I hate when I get a "recovery" email that contains my original password. Not only does that mean that they aren't encrypting it, but they are sending it over a less secure channel.
 
Rob Spoor
Sheriff
Posts: 21919
106
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Slightly less bad but still quite bad is if sites send you the new password. That's just as bad, and makes me change the password immediately. I prefer the correct way to do it - give me a link that's available only very temporarily (using some sort of token; rather have it available for hours than days), and let me fill in a new password on the site opened by the link.
 
Dave Tolls
Rancher
Posts: 4540
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've got one.
Sites that have a max size for your password.
Bit of a giveaway that they're rather unlikely to be hashing it in any way.
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:I've got one.
Sites that have a max size for your password.
Bit of a giveaway that they're rather unlikely to be hashing it in any way.



Yes and no. I despise password requirements that have me jump lots of hoops to "make sure" my password is "strong" - or rather I did untill I started using a password manager.
A maximum password length that is too restrictive is definitely annoying, but I disagree that a max length is a giveaway for plain text storage.
Yes, digests have a fixed-length anyway, so a restriction might seems unnecessary, but hashing can be fairly computationally intensive - in fact this is a goal of algorithms that use key stretching.
If a maximum length is not enfoced in such a case the security mechanism for securely storing passwords can be very easily used as an attack vector in a DoS attack.
 
Dave Tolls
Rancher
Posts: 4540
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good points.
I was thinking more of the unnecessarily strict limitations (eg 12 characters).
That tends to muck up some of the password management tools.

I will say that it is not as prevalent as it was say 5 years ago.
Or maybe I just haven't noticed.
 
I hired a bunch of ninjas. The fridge is empty, but I can't find them to tell them the mission.
Try Free Java/.NET Libraries for Word Excel PowerPoint and PDF
htttp://www.e-iceblue.com/free-apis.html
    Bookmark Topic Watch Topic
  • New Topic