我工作的组织使用PPolicy(OpenLDAP模块)自动加密和哈希密码。不幸的是,我无法访问运行OpenLDAP服务器的机器,所以我无法查看配置文件。从我所看到的情况来看,几乎所有东西都是使用默认设置进行设置的。
我希望能够为特定用户检索salt。如果我查看用户的属性,userPassword是SSHA密码。我没有看到任何有关该特定用户的盐的信息。我最后查看了LDAP模式,我也没有看到任何关于盐的信息。
如果您猜测每个用户存储盐的位置,它会在哪里?我知道这很模糊,可能不是很多信息,但我在OpenLDAP文档中找不到任何地方可以解释存储的唯一盐的确切位置。也许之前配置过OpenLDAP服务器的人会知道默认位置在哪里。
谢谢。
答案 0 :(得分:17)
使用SSHA,通常将salt附加到SHA1哈希,然后整个事务是Base64编码(我从未见过没有以这种方式执行SSHA的LDAP)。您应该能够通过查看userPassword属性来说明这一点。如果它的长度为28个字符,最后一个=,那么它只是哈希值。
如果Base64值为32个字符长或更长,则它包含散列和salt。 Base64解码该值并去掉前20个字节,这是SHA1哈希。剩下的字节是盐。
示例:
Base64 encoded hash with salt
userPassword: {SSHA}MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0
Base64 decoded value
SHA1 Hash Salt
--------------------++++
123456789012345678901234
编辑:经过仔细检查后,似乎有时会支持可变长度的盐。更正了编码说明以解决此问题。
答案 1 :(得分:0)
Syon的帖子对我帮助很大,谢谢!我认为对于正在努力解决这个问题的其他人来说,工作测试会是一个很好的补充;)。
public class SshaPasswordVerifyTest {
private final static int SIZE_SHA1_HASH = 20;
@Test
public void itShouldVerifyPassword() throws Exception{
String password = "YouNeverGuess!";
String encodedPasswordWithSSHA = "{SSHA}M6HeeJAbwUCzuLwXbq00Fc3n3XcxFI8KjQkqeg==";
Assert.assertEquals(encodedPasswordWithSSHA, getSshaDigestFor(password, getSalt(encodedPasswordWithSSHA)));
}
// The salt is the remaining part after the SHA1_hash
private byte[] getSalt(String encodedPasswordWithSSHA){
byte[] data = Base64.getMimeDecoder().decode(encodedPasswordWithSSHA.substring(6));
return Arrays.copyOfRange(data, SIZE_SHA1_HASH, data.length);
}
private String getSshaDigestFor(String password, byte[] salt) throws Exception{
// create a SHA1 digest of the password + salt
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(password.getBytes(Charset.forName("UTF-8")));
crypt.update(salt);
byte[] hash = crypt.digest();
// concatenate the hash with the salt
byte[] hashPlusSalt = new byte[hash.length + salt.length];
System.arraycopy(hash, 0, hashPlusSalt, 0, hash.length);
System.arraycopy(salt, 0, hashPlusSalt, hash.length, salt.length);
// prepend the SSHA tag + base64 encode the result
return "{SSHA}" + Base64.getEncoder().encodeToString(hashPlusSalt);
}
}
答案 2 :(得分:0)
在PHP中,这会将纯文本密码(通常由用户输入)与给定的ssha散列(通常存储在数据库中)进行比较:
private function checkSshaPassword($encrypted_password, $password)
{
// get hash and salt from encrypted_password
$base_64_hash_with_salt = substr($encrypted_password, 6);
$hash_with_salt = base64_decode($base_64_hash_with_salt);
$hash = substr($hash_with_salt, 0, 20);
$salt = substr($hash_with_salt, 20);
// hash given password
$hash_given = sha1($password . $salt, true);
return ($hash == $hash_given);
}