我正在尝试从此处[LDIF示例] [1]使用LDIF的简单LDAP示例。我能够设置所有内容并使用默认用户/密码正确运行。
但是,我试图生成新用户,并且我使用下面的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;
}
上面的示例链接中的密码检查代码:
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。
答案 0 :(得分:1)
您的函数看起来不错,应该输出正确的加盐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);
如果您不想加盐,则需要注释掉以下行(带有空盐字符串,它仍然是“盐”,并且不会产生与不加盐相同的输出):>
md.update(salt.getBytes(StandardCharsets.UTF_8));
根据以上几点设置正确的存储方案前缀。例如,将SHA-1与salt配合使用,ldif中的password属性值应如下所示:
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
的密码存储答案 1 :(得分:0)
您可以将其用于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;
}