OpenLDAP Faq-O-Matic : OpenLDAP Software FAQ : Configuration : SLAPD Configuration : Passwords : 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 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 abcd123will 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}7c3607b8e61bcf1944e9e8503a660f21f4b6f3f1and 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: | Which RFC 2307 password schemes are recommended and why? |
Next: | What are {MD5} and {SMD5} passwords and how do I generate them? |
|