https://issues.apache.org/bugzilla/show_bug.cgi?id=53785

--- Comment #6 from da...@leppik.net ---
> > Tomcat only supports bidirectional hashes
>
> I am sure that you are wrong in the above statement. If I missed something, 
> please define what you mean by "bidirectional".
>
> All cryptographic hash functions supported by Tomcat are one-way (as a hash 
> function should be).

Bidirectional in the sense that the same function is used for password checking
and password hashing.

I am making a distinction between the underlying general-purpose hash algorithm
and the password hashing algorithm.  Although password hashing algorithms are
built on top of general-purpose hash algorithms, they may include additional
steps, such as salting.

A password API which includes salt is unidirectional in the sense that the same
function is not used both for encryption and decryption.  Thus it is not
possible to do a string comparison between two hashes in order to validate a
password, as is done by Tomcat.

Since Tomcat does password checking like this:

  validated = (digest(credentials).equals(dbCredentials));

you cannot use a system such as bcrypt (or any API with built-in salt) which
has a separate function for validation.

Mind you, bcrypt is built on top of Blowfish, but from a user's perspective it
is more than just a front end to Blowfish.  A bcrypt hash includes the Blowfish
hash, the salt, and the cost (log of number of iterations)-- all of which are
required for validation.

The cost is a core feature of bcrypt:  the user can specify how expensive
password checking is, and therefore how long brute force password guessing will
take.

There is another password hashing algorithm, scrypt, which defines cost in
terms of time and memory.  You'll also hear about PBKDF2 as well, although it
is not so much an API as recommended procedures for password encryption
(described in RFC 2898).


The point is that to do proper password checking you can't just do this (in
JDBCRealm):

  validated = (digest(credentials).equals(dbCredentials));

as it doesn't work with salt;  nor can you do this:

  validated = (digest(credentials, salt).equals(digest(dbCredentials, salt)));

as it doesn't work with a cost function; and while you could do this:

  validated = (digest(credentials, salt, cost).equals(digest(dbCredentials,
salt, cost)));

that's just getting silly-- and it won't work anyway since PBKDF2 requires that
you specify an additional algorithm.  It's a lot more general and future-proof
to just do this instead:

  validated = validate(credentials, dbCredentials);

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to