fangpsh's blog

OpenLDAP 的SSHA

LDAPworm.gif

最近折腾了一下OpenLDAP,密码用的哈希算法是SSHA,SSHA 其实就是加盐的SHA1salted SHA1,加盐增加了利用彩虹表碰撞的难度。

摘一段官网FAQ的perl代码:

#! /usr/bin/perl
#
# This small script generates an Seeded SHA1 hash of 'secret'
# (using the seed "salt") for use as a userPassword or rootpw value.
#
use Digest::SHA1;
use MIME::Base64;
$ctx = Digest::SHA1->new;
$ctx->add('secret');
$ctx->add('salt');
$hashedPasswd = '{SSHA}' . encode_base64($ctx->digest . 'salt' ,'');
print 'userPassword: ' .  $hashedPasswd . "\n";

过程很简单:

'{SSHA}' + base64_encode( SHA1(password + salt) + salt )

也可以直接使用OpenLDAP 提供的slappasswd 生成:

>slappasswd -h {SSHA} -s password

'{SSHA}0c0blFTXXNuAMHECS4uxrj3ZieMoWImr'

需要注意OpenLDAP SSHA 的salt 长度默认为4个字节。


Python 可以直接用PassLib 这个库,class passlib.hash.ldap_salted_sha1,简单快捷,也有对应的 verify 函数。

🌰 :

from passlib.hash import ldap_salted_sha1 as ssha

def encrypt_password(self, password):
    return ssha.encrypt(password, salt_size=4)

def verify_password(self, name, password):
    password_hash = self.get_user(name).password
    return ssha.verify(password, password_hash)

在给walle 添加LDAP 支持的时候,发现无论如何都是用户名和密码不一致,耐心看了下代码,发现作者写错了,似乎是直接抄的phpldapadmin 的代码🌚🌝:

public function validatePassword($password) {
    $encryptionType = strstr(substr($this->_password, 1), '}', true);
    return self::generate_password($password, $encryptionType) == $this->_password;
}

generate_password 里面用随机的salt 生成了一个hash,来校验,怎么可能会一样嘛。自己改了本地的代码,提了一个issue

正确的做法应该是取出userPassword 的salt,和用户输入的密码生成hash,再做对比,参考case ssha

case 'ssha':
   # Check php mhash support before using it
   if (function_exists('mhash')) {
       $hash = base64_decode($cryptedpassword);

       # OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20.
       $salt = substr($hash,20);
       $new_hash = base64_encode(mhash(MHASH_SHA1,$plainpassword.$salt).$salt);

       if (strcmp($cryptedpassword,$new_hash) == 0)
           return true;
       else
           return false;
    } else {
        error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
        }

break;

新的一周又开始咯😆 。