Java 生成的密码不适用于 LDIF 文件

Java generated password not working on LDIF file

我正在尝试使用来自此处 [LDIF 示例][1] 的 LDIF 的简单 LDAP 示例。我能够设置所有内容并 运行 使用默认值 user/pass 正确设置它。

但是,我正在尝试生成新用户,我使用下面的 Java 代码为 "joe" 生成密码,但它似乎不起作用:

 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;
    }

上面示例 link 中用于检查密码的代码:

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");
    }

这是带有密码的 LDIF 文件片段:

  //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

我给 joe 使用的密码是 "joe",我似乎无法接受它。加密方式不同吗?顺便说一下,我正在使用 Windows。

您可以将其用于 SHA-512 您使用 MessageDigest.getInstance("SHA-1") -->MessageDigest.getInstance("SHA-512");

的实例
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public String get_SHA_512_SecurePassword(String passwordToHash, String   salt){
String generatedPassword = null;
    try {
         MessageDigest md = MessageDigest.getInstance("SHA-512");
         md.update(salt.getBytes(StandardCharsets.UTF_8));
         byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
         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;
}

请检查这个问题

您的函数看起来不错,应该会输出正确的加盐 SHA-1 哈希值。

但是,您的 LDIF 文件中的存储方案前缀应该是 {SSHA}(用于加盐 SHA1)而不是 {SHA} - 或者您不打算使用加盐 (?)。

此外,哈希算法的实际输出是二进制数据,可以用十六进制或 base64 字符串表示。 LDAP 存储方案使用 base64 编码。

你能做什么?

  • 在你的 LDIF 中我们可以识别十六进制字符串,所以第一件事是使哈希编码为 base64 而不是十六进制,具体取决于导入的 base64 包:

    // Using org.apache.commons.codec.binary.Base64 
    generatedPassword = Base64.encodeBase64String(bytes);
    
    // Using java.util.Base64 
    generatedPassword = Base64.getEncoder().encodeToString(bytes);
    
  • 如果您不想加盐,则需要注释掉以下行(如果加盐字符串为空,它仍然是 "salt",并且不会产生与不加盐):

    md.update(salt.getBytes(StandardCharsets.UTF_8));
    
  • 根据以上几点设置合适的存储方案前缀。例如,使用带盐的 SHA-1,ldif 中的密码属性值应如下所示:

    userPassword: {SSHA}<base64_encoded_hash>
    

其他一些需要考虑的事情:

  • OpenLDAP 支持以下加密方案:SHA、SSHA、MD5、SMD5 和 CRYPT。

  • SHA 和 SSHA 都使用 SHA-1 算法。

  • 要支持 SHA-2 及其变体,请使用 slapd 的 pw-sha2 覆盖(支持 SHA-224、SHA-256、SHA-384、SSHA-224、SSHA- 256,SSHA-384)。它既可以用 slapd 静态编译,也可以动态加载,因为它启用了模块支持。

另请参阅:14.4。来自 https://www.openldap.org/doc/admin24/security.html

的密码存储