Search code examples
javaspringldapsha

Java generated password not working on LDIF file


I am trying a simple LDAP example using LDIF from here [LDIF example][1]. I was able to setup everything and run it correctly using the default user/pass.

However, I am trying to generate new users and I used the Java code below to generate passwords for "joe" but it doesn't seem to work :

 import java.nio.charset.StandardCharsets;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;

   private static String get_SHA_1_SecurePassword(String passwordToHash)
    {
        String generatedPassword = null;

        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] bytes = md.digest(passwordToHash.getBytes());
            StringBuilder sb = new StringBuilder();
            for(int i=0; i< bytes.length ;i++)
            {
                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
            }
            generatedPassword = sb.toString();

        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        return generatedPassword;
    }

Code for checking password from the sample link above:

public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userDnPatterns("uid={0},ou=people")
                .groupSearchBase("ou=groups")
                .contextSource()
                    .url("ldap://localhost:8389/dc=springframework,dc=org")
                    .and()
                .passwordCompare()
                    .passwordEncoder(new LdapShaPasswordEncoder())
                    .passwordAttribute("userPassword");
    }

Here is the LDIF file snippet with the passwords:

  //working copy for ben from example
    dn: uid=ben,ou=people,dc=springframework,dc=org
    dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben Alex
sn: Alex
uid: ben
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=

    //new user "joe"
    dn: uid=joe,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Joe S
sn: joe
uid: joe
userPassword: {SHA}9c509e6d68f17da2db1c71b5424e54538b6b6ef4

The password I used for joe is "joe" and I cant seem to get it accepted. Is the encryption different? I am using Windows by the way.


Solution

  • Your function looks fine and should output a correct salted SHA-1 hash.

    However, the storage scheme prefix in your LDIF file should be {SSHA} (for salted SHA1) instead of {SHA} - or you did not intend to use salt (?).

    Also, the actual output of a hash algorithm is binary data which can be represented in hexadecimal or base64 strings. LDAP storage schemes use base64 encoding.

    What can you do ?

    • In your LDIF we can recognize hex strings, so the first thing is to make that hash encoded in base64 instead of hexadecimal, depending on imported base64 package :

      // Using org.apache.commons.codec.binary.Base64 
      generatedPassword = Base64.encodeBase64String(bytes);
      
      // Using java.util.Base64 
      generatedPassword = Base64.getEncoder().encodeToString(bytes);
      
    • If you don't want to salt, you need to comment out the following line (with an empty salt string it is still "salt" and won't yield the same output as no salting) :

      md.update(salt.getBytes(StandardCharsets.UTF_8));
      
    • Set the proper storage scheme prefix according to the point above. For example, using SHA-1 with salt, the password attribute value in ldif should look like this :

      userPassword: {SSHA}<base64_encoded_hash>
      

    A few other things to consider :

    • OpenLDAP supports the following encryption scheme : SHA, SSHA, MD5, SMD5 and CRYPT.

    • SHA and SSHA both use SHA-1 algorithm.

    • To bring support for SHA-2 and its variants, use slapd's pw-sha2 overlay (support for SHA-224, SHA-256, SHA-384, SSHA-224, SSHA-256, SSHA-384). It can be either compiled statically with slapd, or loaded dynamically since it has module support enabled.

    See also : 14.4. Password Storage from https://www.openldap.org/doc/admin24/security.html