- Neil Smithline
I use a very similar scheme in my applications, but 2 points that came to mind whilst reading.
- Iterations of at least 1000 times seemed a bit excessive, but it is in the standard and I'm in no way qualified to critise.
- Instead of storing salt in it's own field I usually include it amongst the password (i.e characters 2, 4, 7, 13, 17, 19) to make it that bit harder to even find the salt value. I generally hex encode the hashes as well to make them a bit easier to work with. Assuming decompiled code is available (as an attacker has gained access to the password hashes) this extra salt hiding may not serve any useless purpose.
- I think that the above comment about hiding the bits in the password should just tossed. First, it is basically arguing security by obscurity - never a good practice. Second, it states that the bit hiding isn't helpful when the source code is available. Being that this article is discussing hashing in "Java" specifically and Java decompilation is a well-known and freely available technology, it seems that there is no need to mention hiding of the salt unless it is in reference to other languages. Eg: "In languages other than Java, where obtaining the source code can be difficult and reading the machine code is awkward, hiding the bits of the salt within the hashed password might provide some extra security.(And comments probably should be signed. Four tilde's "~ ~ ~ ~", without the intervening spaces, adds your username and timestamps the comment.)
- Neil Smithline 16:46, 13 April 2007 (EDT)
- I'm advocating information hiding, not security by obscurity, albeit a fine line. The case where source is available makes it a pointless exercise from a security perspective, but imagine a badly written webapp provides access to the database. Showing the use of different salts and then making the salt value obvious allows an attacker to perform dictionary attacks. Hiding the salt within the encrypted password makes this almost impossible. Darren 12:34, 17 April 2007 (EDT)
Huh? Repetitive hashing only affects the attacker?
The article states (Hashing_Java#Hardening against the attacker's attack):
- To slow down the computation it is recommended to iterate the hash operation n times. Because hashing is a fast operation, it slows down by a n factor an attacker but not a legitimate user.
I find the second sentence so awkward to parse that I'm not sure if it is incorrect, I'm mis-parsing it, or I'm not understanding what it is saying. My understanding is that doing the hash n times slows down both the attacker, the user, and anyone else who wants to hash, by a factor of n every time they hash. The key here is that most of what a typical user does is not authentication, and most of authentication is not password validation. Other tasks such as database lookups, permission gathering, and session initialization tend to be much slower than password validation (which likely happens entirely in memory in a tight loop and thereby flies by comparison to the DB-based operations). So, while hashing the password n times does slow down hashing for both attackers and typical users, typical users don't really notice it being that hashing is such a small percentage of their total time interacting with the system. On the other hand, an attacker trying to crack passwords spends nearly 100% of their time hashing so hashing n times gives the appearance of slowing the attacker down by a factor of n while not noticeably affecting the typical user.
If someone else takes a look at my comment and the article and agrees, then it should probably just be changed. I would have done this myself but I'm concerned (although not very concerned) that I might be misunderstanding the text.
Neil Smithline 17:09, 13 April 2007 (EDT)
Agree, have changed it - Stephendv 08:06, 14 January 2008 (EST)
Char to byte
password.getBytes() should be password.getBytes("UTF-8")
Changed. Stephendv 08:09, 14 January 2008 (EST)
UnsupportedEncodingException in code sample
The code sample at the end of the article is not compiling for me in Java 6 because of an uncaught exception, UnsupportedEncodingException in the getHash method.