20040114 Wednesday January 14, 2004

MD-5 password encryption and the "secret key" According to a post on the Struts User mailing list, it's possible to encrypt a password using MD-5 (which is one-way), stuff it into a cookie, and then use a server's "secret key" to verify that it's a good one. Since I'm guilty of storing base64 encrypted passwords in cookies for a "Remember Me" feature, I'd love to figure out a more secure way of doing this.

So the question is - is it possible to implement "Remember Me" in J2EE in a secure way?

Setting the cookies on a certain path (i.e. /roller/security/) works, but not on Tomcat 5. I want to securely set my userid/password/rememberMe cookies at the root level of my app, map a filter to login.jsp (dispatcher = forward for TC 5) and be done with it. Posted in Java at Jan 14 2004, 10:27:04 AM MST 6 Comments

Comments:

The other problem with the Roller remember-me implementation is that it puts the username and password on the URL and redirects to the authentication URL. This means that usersnames and passwords may end up in the server log files and other places.

Posted by Dave Johnson on January 14, 2004 at 12:41 PM MST #

You are correct. I tried changing to use a POST and Common's HttpClient to do this, but I found it always routed the user to a common page (i.e. mainMenu.do), rather than the one requested. I have a workaround for this in AppFuse - just encrypting the password programmatically, so it still might show up in the logs, but the password will be encrypted. A better solution would be to map the LoginFilter to "j_security_check" and see if that works - then there's no need for a LoginServlet and redirect. I'm sure there's someway I can map a filter to the authentication process and do any work I need to do without the redirect.

Posted by Matt Raible on January 14, 2004 at 12:49 PM MST #

Nope, mapping to "/j_security_check/*" does not work. Unfortunately, the one way to invoke container-managed authentication programmatically is to redirect to "/j_security_check". What a kludge.

Posted by Matt Raible on January 14, 2004 at 01:06 PM MST #

One possibility is this:
  1. user logs in first time, password hash is computed and compared to database. If it doesn't match, throw error.
  2. Otherwise take the user name (USER), current time (TIMESTAMP) and known-good password digest (MD5(PASSWORD)) and set the cookie value to USER:TIMESTAMP:HMAC(MD5(PASSWORD):TIMESTAMP) where HMAC is a HMAC message digest using the server's secret key. This key could be ephemeral and created when you start the application - just force people to relogin if you restart your application.
  3. When user returns, the system can get the known-good password digest from the database. It verifies that the HMAC digest provided is correct and that TIMESTAMP is reasonably timely. If both conditions are met, access is granted by redirecting to j_security_check with the information cached in the database.

Posted by Bear Giles on January 14, 2004 at 08:13 PM MST #

<em>> This key could be ephemeral and created when you start the application - just force people to relogin if you restart your application.</em>

Does this mean that remember-me would only be good while the server is running? That is, remember me would work only until the server crashes? If not, I dig your solution and will give it a wack in the coming days (weeks?). If it's not persistent between server restarts, that would suck as I'm *always* restarting the server during development and Remember Me is an awesome way to be more efficient (no logging in when testing through a browser).

Posted by Matt Raible on January 14, 2004 at 11:25 PM MST #

You could save the key someplace, ideally in a keystore with the passphrase passed in via JNDI but you could also just save a serialized form of it someplace. You could also eliminate the timestamp and have 'remember me' valid for years. But it's not required if the lifetime of the app server process is adequate for your needs. That allows you to simplify the code.

Posted by Bear Giles on January 15, 2004 at 01:48 PM MST #

Post a Comment:
  • HTML Syntax: Allowed