![](/img/trans.png)
[英]How can I with Ruby check if SHA1 username, password and verifier/salt is correct?
[英]How can I retrieve a salt from LDAP?
我工作的組織使用PPolicy(OpenLDAP模塊)來自動加密和散列密碼。 不幸的是,我無法訪問運行OpenLDAP服務器的機器,所以我無法查看配置文件。 從我所看到的,幾乎所有東西似乎都使用默認設置進行設置。
我希望能夠為特定用戶檢索salt。 如果我查看用戶的屬性,userPassword是SSHA密碼。 我沒有看到任何有關該特定用戶的鹽的信息。 我最終查看了LDAP模式,我也沒有看到任何關於鹽的信息。
如果您猜測每個用戶存儲鹽的位置,它會在哪里? 我知道這很模糊,可能不是很多信息,但我在OpenLDAP文檔中找不到任何地方可以解釋存儲的唯一鹽的確切位置。 也許之前配置過OpenLDAP服務器的人會知道默認位置在哪里。
謝謝。
使用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
編輯:經過雙重檢查,似乎有時支持可變長度的鹽。 更正了編碼說明以解決此問題。
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);
}
}
在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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.