views:

322

answers:

1

For an internal Tomcat/Java/Struts application, we're converting custom-written authentication code to use JDBCRealm. The database is MySQL 5.0, and the passwords are stored as PASSWORD()-encrypted strings. In our version of MySQL, the PASSWORD() function is a non-standard (proprietary?) 41-byte hash. (I know now that we shouldn't be using it for our passwords, but should instead be using SHA1() or MD5(). But here we are.)

Is there any way to use JDBMRealm without forcing all of our users to re-enter their passwords so we can re-encode them? Is there a JDBCRealm digest that will allow us to authenticate against a PASSWORD()-encoded password column?

A: 

New MySQL versions provide a function called OLD_PASSWORD() that digests password in a way backwards-compatible with 4.0 and prior.

What you can do, therefore, is to configure JDBCRealm in such a way that it:

  1. Does not use any kind of digest by itself. This is obviously not ideal even in secure environment and is outright dangerous if your database server lives across untrusted connection. You do this by not specifying digest attribute.
  2. Uses the above OLD_PASSWORD() function to encrypt the password before comparing it with the one from the database. You will have to extend JDBCRealm, this functionality is not provided out of the box. For Tomcat 6.0 you'll have to override authenticate(Connection c, String username, String credentials) method.

You can also use the above approach as part of migration strategy: have the overridden method support both the OLD_PASSWORD() and digest and force users who've authenticated using OLD_PASSWORD() to change their password. With time you'll then hopefully be able to switch to standard digest-based approach.

ChssPly76
I've marked this as a solution for other people, but we've decided to do the Right Thing and fix all of our passwords to MD5-encoded even if it'll annoy our users.
Plutor
I can only envy you - I couldn't afford to annoy my users :-)
ChssPly76