Skip to main content

Encrypted vs Hashed Passwords - Which is better?

Topics like password strength, protection, encryption are almost everywhere these days. Password maintenance related subjects like password managers, recovery tools and crackers are also gaining attention. A user name and a password is a must in almost all software applications like email applications, web sites, mobile and desktop applications; mainly to provide user specific information or functionality.
Security of the password is so much important not because the data stored behind a user account is so much valuable to the owner, but might be to some other bad guy who is looking for personal information. To overcome the pain of memorizing multiple passwords, users might use one single much stronger password across multiple applications which is a bad practice considering the security aspect.

As anyone would guess, most of the application specific databases are having a table named user or users including two columns named user name and password; and interestingly the password in plain text! If your application database is storing passwords in plain text format, there is no hope for security in your application. People would argue that the application is well protected, HTTPS or TLS is in action; so the users are safe. What if someone get access to your database? That is the end of the security of all your users; and if those users were reusing their most secret and strongest password across multiple web sites, can you imagine what will be the situation? If your application stores password in plain text, it must be time to think at least about encrypted passwords.

Is encryption good?

However the intention of this article is not to discuss about plain text passwords, but about encrypted passwords stored in databases. Plain text passwords can be encrypted using symmetric encryption algorithms like DES, AES or with any other algorithms and be stored inside the database. At the authentication (confirming the identity with user name and password), application will decrypt the encrypted password stored in database and compare with user provided password for equality. In this type of an password handling approach, even if someone get access to database tables the passwords will not be simply reusable. However there is a bad news in this approach as well. If somehow someone obtain the cryptographic algorithm along with the key used by your application, he/she will be able to view all the user passwords stored in your database by decryption. "This is the best option I got", a software developer may scream, but is there a better way?

Yes there is, may be you have missed the point here. Did you notice that there is no requirement to decrypt and compare? If there is one-way-only conversion approach where the password can be converted into some converted-word, but the reverse operation (generation of password from converted-word) is impossible. Now even if someone gets access to the database, there is no way that the passwords be reproduced or extracted using the converted-words. In this approach, there will be hardly anyway that some could know your users' top secret passwords; and this will protect the users using the same password across multiple applications. What algorithms can be used for this approach?

Cryptographic hash function

Cryptographic hash functions can be used to achieve one-way-only conversion requirement. As there is no support to go back from converted text to original text, there is no risk involved in the safety of the valuable and secret password. There are many well known and publicly available algorithms for this task, and most popular ones are MD5 and SHA-1. There are freely available tools implementing these algorithms; so incorporating hashed approach into applications is not a pain. Even though these algorithms provide a far better security, both MD5 and SHA-1 are proven to be weak and vulnerable. It is recommended to go with SHA-2 considering the preciousness of the password. However at the moment, there is an open competition to created a replacement algorithm for SHA-2 which is called SHA-3 and this will be available in 2012.

In summary; when an application level security is discussed/designed make sure that passwords are never kept in plain text, but at least in encrypted form; but try to reach the hash function based password handling as much as possible.

Related: Data Encryption Decryption using AES Algorithm, Key and Salt with Java Cryptography Extension


  1. When in doubt, do both; encrypt a hash.

    Though personally, I feel happy as long and passwords aren't stored in plain text.

  2. Hi Kamal,
    do you have any opinion about the following problem?

    Password encryption/hashing guards against internal hijacking (ie. hacking the password database). However even with this solution the password still moves around the network and goes through the application server. That is one can imagine 2 possible attacks:

    1. Many application server sits behind an SSL reverse proxy, that is the password moves in plain text between the SSL proxy and the appserver. Hence one can attack the system by sniffing the internal network communication. I would call this type of attack a 'network attack' that could be made by anyone who has access to the LAN and has a minimal network expertise.

    2. Even if the application server itself supports SSL the password still goes throug the application. Hence one can attack the application itself. I would call this type of attack an 'application attack' that could be made by someone who has access to the application (either at the developer side, ie. access to the source code or at the maintance side, ie. access to the deployed app).

    What is your opinion/experience?


  3. Vagelis GiannadakisOctober 16, 2011 5:35 PM

    @Gyula: Hashing is a "lossy" algorithm by design: when you hash something, you simply cannot get it back. Hashing is a one-way thing. So, there is no point in passing verbatim passwords back and forth between application components to compare them with the passwords in the DB, since you cannot get the original passwords back from the hashes you have there. Instead, the application should apply the exact same hashing algorithm to the password right after the user enters it. Then, it should pass back and forth this hash and compare it with the one in the DB.

    Indeed, even this policy is not completely safe, since someone who gains access to the DB does not get the original passwords, but does get the hashes that they can use to gain access to the application: all they need to do is to masquerade a normal login request.

    To tackle this, you can apply another hashing algorithm to the hash of the original password, or double-hash and store the result in the DB. Subsequent login requests that contain the hash of the entered password are then gone on-the-fly through the second hashing algorithm before they are compared with what is in the DB.

  4. @Vagelis: Equivalent questions apply to your scenario:) If the client does the hashing and sends the hash code instead of the original password, than the attacker won't be able to capture the password - that is ok. However she doesn't have to capture the password in order to break the system. Instead:

    The attacker can and will capture the hash code either by sniffing the network or breaking the (deployed) app. Once the hash is captured the attacker can use it to login. In other words:In either case (either sending the original password or its hash) the attacker might capture the secure token (password or hash) the application uses to authenticate the user:

    BTW there are still differences between these scenarios if we look at the implementation details:

    I. Implementing client side hashing might not be a typical scenario for thin clients might be better suited to fat clients. Though SHA libs exist for Javascript... I've never met web applications where the hashing happened at the browser side...

    II. When using client side hashing the attacker has to hack the original client, ie. she has to rewrite the auth part in order to avoid (double) hasing (since only the password hash is captured). Meanwhile if using server side hashing then the attacker can use the original client (since password is captured). So in the "client side hashing" scenario the attacker has a bit more to work...


  5. Hi Gyula,

    Both points are find with me. Network monitoring will be used by bad guys to trace what is sent through the wire.

    My target is to highlight the fact that storing plain text or encrypted values in a database has a risk even when the system is not receiving login requests.


  6. Tarandeep Singh SawhneyOctober 29, 2011 10:05 PM

    DO NOT use HTTP Basic Authentication, also i agree with above statements suggesting DO NOT store passwords, not even encrypted passwords.

    Instead, one of the security best practice is to just store OAuth tokens. Any thoughts?

  7. Vagelis GiannadakisOctober 29, 2011 10:07 PM

    The point is there's no such thing as 100% security. You're always vulnerable to a degree, what's important is to expose as little of your system as is necessary to provide the required functionality AND correctly balance desired and needed security with the costs related to achieving it.

    For example, you can prevent terminal access by shutting-off sshd, requiring physical presence with three-factor authentication (smart-card, PIN and fingerprint) and locking the server in a concrete room, behind a huge door with a voice-recognizing and iris-reading lock. Would the desired degree of security justify the costs of building all this? Especially when you know even this is far from 100% secure!

  8. Balázs BessenyeiOctober 29, 2011 10:09 PM

    In case of hashing, don`t forget to add static and dynamic salt as well. Static salt prevents/complicates pre generated hash tables. Dynamic salt prevents reusing previous hash attempts between different hashed passwords. Also guaranties that even if 2 user has the same password, the actual hash will be quite different.

  9. @Balázs: That's an interesting point... Meanwhile to my understanding there might be one practical challenge when using salts.

    Salting seems to work iff the same salt was applied for both the persisted password hash and the one the user gave at the password prompt. The question is: who remembers the salt?

    The user wouldn't not remember it since the password is enough for her:) The client machine cannot remember the salt either (well if we assume a multi device environment (ie. the user may access the system from different devices) which is quite typical nowdays).

    Hence it seems that the server should store the salt, which means (if assuming a simple scenario) that (I) hashing should be performed at the server side thus (II) the password travels through the wire.

    Sending the password through the wire is ok for me in simple cases and combined with SSL. However there might be a problem with this approach. If using server side hashing, it doesn't guard against external attacks, ie. in this case an attacker has to crack the original password and not the hash. Hence it seems that salting could guard against internal attacks... which itself is a tough task...

    Any practical experience regarding this, ie. where to apply salting/hashing?

  10. Balázs BessenyeiOctober 29, 2011 10:10 PM

    In case of SSL the channel can be considered secure so transferring passwords through that connection can be considered safe as well. In case of the salt is generated on the client side then it also needs to be transmitted so a successful Man in the Middle attack can capture both.

    Client side hashing can work, if the Client and the Server has a shared secret. That can be used to regenerate the hash on both side, to verify if the client is authentic or not. There are few standards to do that. However the channel itself will still be insecure. So using SSL/TLS is still a good idea.

    In case of this solution you should consider adding a changeable data to the hash. Like a time window. This would prevent reusing the hash if it is captured.

    You can try cryptographically sound hashes (secure if possible). But they should consist of multiple fields, contain shared secret and probably time window data. This way the server can recreate and compare it with the received one.
    (This is solution is used by the SMGP and SMPP protocols to authenticate, without sending the password directly)

    I see an attempt here to reinvent, the well regarding how to do a secure handshakes on an unsecured connection. There are several solutions for it, some of them are more secure than others. Like a very basic one used by PPP connections, if the provider isn`t dumb enough to use PAP.

    In case of a browser, your choices are extremely limited, unless you are wiling to implement a cryptographically secure hash algorithm in JavaScript or using browser extension or plug-ins to provide that algorithm. So secure connection still sounds better for common use cases in the browser.

  11. These discussion are great. Most of the issues can resolve web page access, webservice access or other application resource in our control, Still there are some gaps in security when we call resource like database, or Directory Server for Single sign on . The password in that case needs to be decrypted to clear Text before sending to these resources. These resources are in private network thus dont pose that much danger but the password is passed as clear text in these cases. Some of the directory services provide can be run on SSL. Can Oracle DB listen secure connection? Securing these may be a overkill in private network. but with Cloud computing there should be ways to secure these calls too.

  12. @Ranajit: Though I've got no experience with it, according to the following documentation Oracle seems to support SSL at the JDBC level:

  13. @Balázs: In my limited experience... shared secret and time window based solutions occured in the case of system integration. For user auth I've just met password and cert based techniques. Do you have a case for user auth with shared secret (excluding the case of public key:))?

  14. When considering security one needs to understand a few things:
    The risk profile
    The attack surface

    Understanding these two things enables you to make the right decision on the level of security required.

    In terms of authentication there are three main ways of dealing with it (and more and more they are being combined)

    Something you know
    Something you have
    Something you are

    This is a good explanation

    If you combine something you know (a pass phrase), with something you have (an RSA secure id) then you are ready to say, I am starting on the path to securing my application :)

    Remember security is an illusion, what we are doing is making exploitation take more and more effort, but no system is ever secure.

  15. This comment has been removed by a blog administrator.

  16. This comment has been removed by a blog administrator.

  17. This comment has been removed by a blog administrator.

  18. I think the wrong security architecture is being discussed here. Security tooling in the DMV should be verifying the user ID and password. At most, the application should see only the user ID


Post a Comment

We appreciate your opinions, suggestions and criticism.

Popular posts from this blog

Web Services with Apache Axis 1.4 Tutorial: server and client sides

Java Sorting: Comparator vs Comparable Tutorial

Creative Commons License Digizol by Kamal Mettananda is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 License .
URL of this page must be supplied in attribution
© 2004-2017