https://issues.apache.org/bugzilla/show_bug.cgi?id=53785
Priority: P2
Bug ID: 53785
Assignee: [email protected]
Summary: Modern password hashing for built-in Realms
Severity: enhancement
Classification: Unclassified
OS: All
Reporter: [email protected]
Hardware: All
Status: NEW
Version: unspecified
Component: Catalina
Product: Tomcat 6
Password-based authentication for the built-in realms can currently use three
digestion algorithms from the java.security.MessageDigest class (SHA, MD2, or
MD5). All of these are out of date*, and each Realm implementation does its
own comparison of the password to the saved digest.
[*It's not clear whether Java's SHA is SHA-1 or one of the SHA-2 algorithms.
SHA-1 is obsolete; SHA-2, potentially less so.]
I recently created my own custom Realm in order to support bcrypt. While I do
not claim that bcrypt is the right algorithm for everyone, it is a much better
default than the current built-in options-- so Tomcat should offer it.
However, rather than being a general purpose hash function, bcrypt a one-way
hash designed for passwords. The salt is built into the hash in such a way
that it can't be extracted. That is to say, you can't say:
if ( bcrypt.hash(password1) == bcrypt.hash(password2) )
log("Passwords match");
because every time you hash a password, you get a different result. This is a
security feature, since novices won't mismanage the salt. Instead, you call:
String hash = BCrypt.hashpw("hello"); // To hash, not to check
if (BCrypt.checkpw(passwordFromLoginForm, savedPasswordHash))
log("Passwords match");
This example uses the JBCrypt implementation at
http://www.mindrot.org/projects/jBCrypt/
Like I said, I don't think BCrypt is the right solution for every user. See
http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html and
http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage
Also note that NIST will recommend a new secure hashing algorithm soon (
http://csrc.nist.gov/groups/ST/hash/timeline.html ) although that will be a
general purpose cryptographic hash function, not an out-of-the-box password
hash format like bcrypt.
Instead, I propose that we make three (or four) changes:
1. Update all applicable subclasses of RealmBase to call a new method,
RealmBase.checkDigest(String credentials, String savedHash), instead of each
implementation doing a string comparison against the realms.
2. Implement RealmBase.checkDigest with the following rules:
a. If digest == null, implement the current string comparison.
b. If digest is "SHA", "MD2", or "MD5", compare with the current algorithm.
c. If digest is the name of a Java class, try calling
checkPassword(credentials, savedHash) on the class, both as a static method and
on an instance created with no constructor arguments.
3. (Depending on legal issues) Bundle Tomcat with JBCrypt, thus providing a
secure hash out of the box.
4. Write unit tests and documentation and update Tomcat 7+ with the new code.
Of course, we could jump ahead and implement this in Tomcat 8, since this is a
public API change.
I will check with my boss to see if I can take the time to implement this. Of
course, I'd prefer to get feedback before I go ahead with it.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]