Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top