(Answer) (Category) OpenLDAP Faq-O-Matic : (Category) OpenLDAP Software FAQ : (Category) Configuration : (Category) SLAPD Configuration : (Category) Passwords : (Answer) What are {SHA} and {SSHA} passwords and how do I generate them?
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 (Xref) What are RFC 2307 hashed user passwords?.
{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:: e1NIQX1mRFlIdU9ZYnp4bEU2ZWhRT21ZUElmUzI4L0U9
Confused 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: (Answer) Which RFC 2307 password schemes are recommended and why?
Next: (Answer) What are {MD5} and {SMD5} passwords and how do I generate them?
This document is: http://www.openldap.org/faq/index.cgi?file=347
[Search] [Appearance]
This is a Faq-O-Matic 2.721.test.
© Copyright 1998-2013, OpenLDAP Foundation, info@OpenLDAP.org