Using Hashed Passwords


Storing plain-text passwords, whether in local files or in the database, can be worrisome. Even if you take care to protect the resources, exposing passwords in plain text is always a concern. The login modules we have seen so far allow for password hashes to be used in place of plain-text passwords.

You can think of a hashed password as an encrypted form of a password that can't be decrypted. If someone were to obtain the hashed password, they would have no way to recover the original password. To verify that a user's password is correct, you can apply the hash function to the value and see if the resulting hashed value is the same as the stored hash value. If it is, the password is correct. Using hashed passwords doesn't guarantee the security of your passwords, but it does help keep them out of plain sight.

How do I do that?

To use hashed passwords, you must configure the login module to use the desired hashing algorithm. Additionally, since hashed passwords are binary data, you will need to decide how the passwords will be encoded as text strings. Both of those configuration options are set as options on the login module.

Here is the login module from the previous lab, with password hashing enabled:

     <application-policy name="todo">         <authentication>             <login-module                 code="org.jboss.security.auth.spi.DatabaseServerLoginModule"                 flag="required">                  <module-option name="dsJndiName">                     java:/DefaultDS</module-option>                 <module-option name="principalsQuery">                     select passwd from USERS where login=?                 </module-option>                 <module-option name="rolesQuery">                     select role, 'Roles' from USER_ROLES where login=?                 </module-option>                 <module-option name="hashAlgorithm">MD5</module-option>                 <module-option name="hashEncoding">BASE64</module-option>              </login-module>         </authentication>     </application-policy> 


Note: Base64 encoding produces text strings that are more compact than hex-(Base16) encoded ones.

hashAlgorithm tells us the name of the message digest algorithm to use. We've used MD5 here. Another commonly used message digest algorithm is SHA. You can use any message digest algorithm supported by your JCE provider. The hashEncoding value is used to translate the binary hash into a string value. JBoss supports Base64 and hex encoding.

With this configuration, the login module expects to find hashed passwords in the database instead of plain-text passwords. But how do you get the hashed passwords there? Your user management code will need to take care of that. Since the algorithm and encoding methods are standard, this isn't hard to do. The following code uses the org.jboss.security.Util helper class to create a hashed password using MD5 and Base64 encoding:

     import org.jboss.security.Util;     public class Hash     {         public static void main(String[  ] args)             throws Exception         {             if (args.length != 1) {                 System.out.println("ARGS: password");                 return;             }             String password = args[0];             String result   = Util.createPasswordHash("MD5",                                                       Util.BASE64_ENCODING,                                                       null,                                                       null,                                                       password);             System.out.println("MD5(" + password +")=" + result);         }     } 

If you need to generate just a few passwords for test purposes, OpenSSL is a good cross-platform tool. It supports both MD5 and SHA digests as well as Base64 encoding. Here are examples that illustrate both of these digest algorithms:

     [hash]$ echo -n mypassword | openssl dgst -md5 -binary | openssl base64     NIGde+6ruSYKXIVLyFs+RA=  =     [hash]$ echo -n mypassword | openssl dgst -sha -binary | openssl base64     eJrcMN01ZfbtLMPmcsR7b0JRvk4= 


Note: See http://www.openssl.org/ for more information about OpenSSL.

You can put these values directly into the passwd column of a user in the database. Once you update the plain-text values in the database with the hashed values, you will be able to access the ToDo application again.

What just happened?

You switched from using plain-text passwords to using hashed passwords. You can use password hashing with almost all of the JBoss-provided login modules. In each case the configuration options are exactly the same.


Note: Don't be careless with hashed passwords. You should still treat them as confidential information.

We'll repeat a point we made earlier. Hashed passwords don't guarantee security. Weak passwords are still susceptible to dictionary attacks, for example. Furthermore, the hashing mechanism supported by JBoss doesn't use any form of salt, which means that two users with the same password will have the same hashed value. None of this is to say that hashed passwords are not valuable. They are. However, don't assume that just because you are using them you don't need to take care of your password data.

: Our Approach to Application Security

J2EE security is so limited as to be almost entirely useless. You can count on it to restrict access to your application, but it doesn't help much with the fine-grained user-based or object-based access control policies you generally want to apply in an application. In other words, J2EE security helps you say "only valid users should be able to use the application," but it doesn't help you say "users should only be able edit objects they created."

JBoss provides some limited help in implementing instance-based security by allowing you to define a SecurityProxy for each bean type. You can implement any sort of access policy you want in the proxy, and JBoss will make sure that your policy is consulted before each access to a bean.

The SecurityProxy does keep your application code free of instance-based security checks, but you still manage the security details yourself at the presentation tier. Thinking about the ToDo application, a SecurityProxy could enforce the rule that users can only modify their own tasks, but it would be rather rude of the application to present a user with the option to edit a task only to fail when he tries to save it because that security policy is only reflected in the bean.

There's nothing in J2EE, or in JBoss, that provides a real framework for full application security. You are on your own to implement the policy that makes the most sense. In the ToDo application, we've decided not to worry about bean-level security. The beans are entirely local to the application, so we've chosen to just apply security at the presentation tier.

When displaying the task list, the controller only asks for tasks for a specific user. Only those tasks are displayed to the user, and the user can only edit those tasks. Assuming the presentation tier cannot be hacked to allow access to objects other than the ones presented to the user, this is sufficient to limit access to the application. If you don't want to rely on the presentation tier as the only implementation of the security policy, you could couple it with a SecurityProxy on the EJBs to provide the hard enforcement of rules.




JBoss. A Developer's Notebook
JBoss: A Developers Notebook
ISBN: 0596100078
EAN: 2147483647
Year: 2003
Pages: 106

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net