| 
 | 
 
 | 
| 
OpenLDAP supports RFC 2307 passwords, including the
{SHA}, {SSHA} and other schemes.  Such passwords may
be used as userPassword values and/or rootpw value.
See  | |
| {SHA} and {SSHA} are RFC 2307 passwords schemes which use the SHA1
secure hash algorithm.  The {SSHA} is the seeded varient.  {SSHA}
is recommended over other RFC 2307 schemes.
 
Netscape provides a technical note on how to generate {SHA} and
{SSHA} password values.  See: http://developer.netscape.com:80/docs/technote/ldap/pass_sha.html
  | |
#! /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"; | |
#! /usr/bin/perl
#
# This small script generates an SHA1 hash of 'secret' for use
# as a userPassword or rootpw value.
#
use Digest::SHA1;
use MIME::Base64;
$ctx = Digest::SHA1->new;
$ctx->add('secret');
$hashedPasswd = '{SHA}' . encode_base64($ctx->digest,'');
print 'userPassword: ' .  $hashedPasswd . "\n"; | |
| When generating passwords in PHP, some confusion may occur. First of all, make use of the 'slappasswd' utility to generate a password, so you can check if your PHP routines are correct. (The slappasswd utility is part of the openldap distribution). The command         slappasswd -h {SHA} -s abcd123
will generate 
        {SHA}fDYHuOYbzxlE6ehQOmYPIfS28/E=
so, in your entry, an attribute like this could be specified:
        userPassword: {SHA}fDYHuOYbzxlE6ehQOmYPIfS28/E=
but when you do a slapcat or ldapsearch and the output is in LDIF format, the userpassword will be base_64 encoded, and it will look like this:
userPassword:: e1NIQX1mRFlIdU9ZYnp4bEU2ZWhRT21ZUElmUzI4L0U9Confused yet ? Now enter PHP (< 5). You would like to generate a {SHA} password from a cleartext password that was entered in a FORM by a user, which is held in $pass. It would be easy to do:         $userpassword = "{SHA}" . sha1( $pass );
but that will generate:
        {SHA}7c3607b8e61bcf1944e9e8503a660f21f4b6f3f1
and altough that looks nice, it won't work.
That's because the PHP sha1() function delivers a Hex encoded string.
In PHP >= 5 you can set a boolean, to omit that:
        $userpassword = "{SHA}" . sha1( $pass, TRUE );
but in PHP < 5 you need to do this:
        $userpassword = "{SHA}" . pack( "H*", sha1( $pass ) );
this will generate:
something very ugly that I can't represent here, since it is binary.now to avoid putting the binary stuff into the directory, you need to base_64 encode it, like this:         $userpassword = "{SHA}" . base64_encode( pack( "H*", sha1( $pass ) ) ); 
this will, finally, generate
        {SHA}fDYHuOYbzxlE6ehQOmYPIfS28/E=
and that value should be put into the userPassword attribute.Ace (http://www.qwido.net) 
  | |
#!/usr/bin/env ruby
# Ruby script to generate SSHA (Good for LDAP)
require 'sha1'
require 'base64'
hash = "{SSHA}"+Base64.encode64(Digest::SHA1.digest('secret'+'salt')+'salt').chomp!
puts 'userPassword: '+hash+"\n" | |
| Ruby script to generate SSHA: #!/usr/bin/env ruby require 'sha1' require 'base64' hash = "{SSHA}"+Base64.encode64(Digest::SHA1.digest('secret'+'salt')+'salt').chomp! puts 'userPassword: '+hash+"\n"  | |
| SHA passwords in Python: import sha from base64 import b64encode ctx = sha.new( password ) hash = "{SHA}" + b64encode( ctx.digest() ) And salted SHA (guessing from the perl-examples, haven't tried it): import sha from base64 import b64encode ctx = sha.new( password ) ctx.update( salt ) hash = "{SSHA}" + b64encode( ctx.digest() + salt )  | |
2008/01/10 - Reed O'Brien
SSHA python seeded salted sha password
import hashlib
from base64 import urlsafe_b64encode as encode
from base64 import urlsafe_b64decode as decode
def makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt)
def checkPassword(challenge_password, password):
    challenge_bytes = decode(challenge_password[6:])
    digest = challenge_bytes[:20]
    salt = challenge_bytes[20:]
    hr = hashlib.sha1(password)
    hr.update(salt)
    return digest == hr.digest()
>>> challenge_password = makeSecret('testing123')
>>> challenge_password
    '{SSHA}0c0blFTXXNuAMHECS4uxrj3ZieMoWImr'
>>> checkPassword(challenge_password, 'testing123')
    True
>>> checkPassword(challenge_password, 'testing124')
    False | |
Previous Python method to generate SHA and SSHA password is wrong and works partially with openldap, don't use urlsafe_b64encode
from base64 module who replace "/" by _ and "+" by "-". Use instead the encodestring method from the same module.
So the previous code is : 
import hashlib
from base64 import encodestring as encode
from base64 import decodestring as decode
def makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt)
def checkPassword(challenge_password, password):
    challenge_bytes = decode(challenge_password[6:])
    digest = challenge_bytes[:20]
    salt = challenge_bytes[20:]
    hr = hashlib.sha1(password)
    hr.update(salt)
    return digest == hr.digest() | |
Note that base64.encodestring() appends a newline ("\n") to its output (see http://docs.python.org/library/base64.html), so makeSecret() should probably be modified to strip that newline:
def makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt){:-1] | |
Forgive the formatting errors and typos in my previous edit. Here's what I meant to write 
(note change from open brace to open bracket in to the last line):
Note that base64.encodestring() appends a newline ("\n") to its output (see http://docs.python.org/library/base64.html), 
so makeSecret() should probably be modified to strip that newline:
def makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt)[:-1] | |
If you are stuck on Windows, using the OpenSSL for Windows package: http://gnuwin32.sourceforge.net/packages/openssl.htm The below batch script can generate a {SHA} hash suitable for LDAP passwords: makeshahash.bat: @echo off echo|set /p="{SHA}" echo|set /p="%1" | openssl dgst -sha1 -binary | openssl enc -base64 > makeshahash.bat secret {SHA}5en6G6MezRroT3XKqkdPOmY/BfQ=  | |
Here is an update for Python-based hashing and testing. These functions worked on Ubuntu 12.04 + OpenLDAP 2.4.28-1.1ubuntu4. https://gist.github.com/rca/7217540 Thanks!  | |
| [Append to This Answer] | 
| Previous: | 
 | 
| Next: | 
 | 
  | ||||||||