8 Replies Latest reply on Feb 26, 2011 3:55 AM by bora bora

    Problem with @UserPassword encryption

    Sebastian Lillo Newbie

      Hi, I implemented the new security authentication model in Seam 2.1.2 and it works only when I set @UserPassword with hash  none; when I set @UserPassword with hash sha1 it doesn't autenticate the user. I went to three different online sha1 calculators site to make sure the hash was right for the stored password, but still no luck.


      Is the @PasswordSalt annotation obligatory for this to work ?


      Thanks in advance.

        • 1. Re: Problem with @UserPassword encryption
          Nikolay Elenkov Master

          That doesn't seem to be documented in the Seam reference, but it is a bit more complicated than just hashing the
          user password.


          Seam concatenates a salt value with the specified password and hashes this to generated the password hash.
          If you have the @PasswordSalt annotation on your UserPrincipal class, a random value is generated and
          used as the salt. If you don't, the username is used as the salt.


          Check out PasswordHash#createPasswordKey and PasswordHash#generateSaltedHash to see how those work
          in detail. If you want to generate password hashes to insert directly in the database, use should those
          methods (if you use @PasswordSalt, you should generate and insert the salt as well).


          • 2. Re: Problem with @UserPassword encryption
            Shervin Asgari Master

            Nikolay is right.


            Take a look here:


            Hash user
            This is however the way you do it in Seam 2.1.1
            You have to modify it a bit for it to work with 2.1.2




                 /**
                  * This method will generate a hash password
                  * 
                  * @param password
                  *            - The password in cleartext
                  * @param salt
                  *            - The username is used as salt
                  * @return - hash password based on password and username
                  */
                 public static String generatePasswordHash(String password, String salt) throws GeneralSecurityException {
                      char[] passToChar;
                      byte[] saltToByte;
                      String thePassword;
                      try {
                           passToChar = password.toCharArray();
                           saltToByte = salt.getBytes();
                           AnnotatedBeanProperty<UserPassword> userPasswordProperty = new AnnotatedBeanProperty<UserPassword>(ProcessUser.class, UserPassword.class);
                           // Will get the hash value from annotation UserPassword in ProcessUser.class
                           PasswordHash.instance().setHashAlgorithm(userPasswordProperty.getAnnotation().hash().toUpperCase());
                           thePassword = PasswordHash.instance().createPasswordKey(passToChar, saltToByte, userPasswordProperty.getAnnotation().iterations());
                           return thePassword;
                      } finally {
                           // Ensure that the password is not in memory
                           password = null;
                           passToChar = null;
                           salt = null;
                           saltToByte = null;
                           thePassword = null;
                      }
                 }
            



            • 3. Re: Problem with @UserPassword encryption
              Joshua D Novice

              "The above code doesn't work if  @UserPassword(hash=PasswordHash.ALGORITHM_MD5). The SecretKeyFactory.getInstance() call fails in PasswordHash. The above code works is able to generate a password only if hashAlgorithm is set to null.

              Am I missing something here
              • 4. Re: Problem with @UserPassword encryption
                Nikolay Elenkov Master

                Check out the HashGenerator.java and hashgen.xhtml in the seamspace example.

                • 5. Re: Problem with @UserPassword encryption
                  Joshua D Novice
                  I did check the HashGenerator.java sample..

                  which in turn calls JpaIdentityStore.generatePasswordHash() to generate the password..

                  The method is provided below for clarity..

                     public String generatePasswordHash(String password, byte[] salt)
                     {
                        if (passwordSaltProperty.isSet())
                        {
                           try
                           {
                              return PasswordHash.instance().createPasswordKey(password.toCharArray(), salt,
                                    userPasswordProperty.getAnnotation().iterations());
                           }
                           catch (GeneralSecurityException ex)
                           {
                              throw new IdentityManagementException("Exception generating password hash", ex);
                           }
                        }
                        else
                        {
                           return generatePasswordHash(password, new String(salt));
                        }
                     }

                  -------------------------------------------

                  But the hashAlogrithm parameter in PasswordHash is never set and the logic goes through the else part

                  PasswordHash.createPasswordKey is provided below for clarity ..
                     /**
                      *
                      */
                     public String createPasswordKey(char[] password, byte[] salt, int iterations)
                        throws GeneralSecurityException
                     {
                        if (hashAlgorithm != null)
                        {
                           PBEKeySpec passwordKeySpec = new PBEKeySpec(password, salt, iterations, 256);
                           SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(hashAlgorithm);
                           SecretKey passwordKey = secretKeyFactory.generateSecret(passwordKeySpec);
                           passwordKeySpec.clearPassword();
                           return BinTools.bin2hex(passwordKey.getEncoded());
                        }
                        else
                        {
                           PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA1", "ISO-8859-1", salt, iterations);
                           PBKDF2 pbkdf2 = new PBKDF2Engine(params);
                           return BinTools.bin2hex(pbkdf2.deriveKey(new String(password)));
                        }
                     }

                  Does this mean the hash algorithm set as part of UserPassword is never used?
                  • 6. Re: Problem with @UserPassword encryption
                    Shervin Asgari Master

                    Joshua Daniel wrote on Sep 04, 2009 08:33:



                    The above code doesn't work if  @UserPassword(hash=PasswordHash.ALGORITHM_MD5). The SecretKeyFactory.getInstance() call fails in PasswordHash. The above code works is able to generate a password only if hashAlgorithm is set to null.

                    Am I missing something here


                    What do you mean it doesnt work? It works fine if your userpassword is annotated like this:


                    @UserPassword(hash = "md5")
                         public String getPasswordHash() {
                              return passwordHash;
                         }


                    • 8. Re: Problem with @UserPassword encryption
                      bora bora Newbie
                      Hi, I am trying to use PasswordHash.createPasswordKey and having problems with NoSuchAlgorithmException...I am not doing anything fancy, very simple xhtml view calling a bean to create a hashed password.
                      But I keep getting "java.security.NoSuchAlgorithmException: MD5 SecretKeyFactory not available"...

                      Anyone knows why this is happening? Do I need to install a Security Provider or something somewhere? I think I am missing something basic here..

                      I am using JDK 1.6.0_21, JBoss AS 5.1.0.GA, Seam 2.2.1.Final...

                      Please let me know what I am missing.
                      Also I can provide code if it would help but it's not really different than the stuff in the seamspace hashgen.xhtml..