Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python hashing and test functions for user passwords stored in OpenLDAP.
#!/usr/bin/env python
"""
http://www.openldap.org/faq/data/cache/347.html
As seen working on Ubuntu 12.04 with OpenLDAP 2.4.28-1.1ubuntu4
Author: Roberto Aguilar <roberto@baremetal.io>
"""
import hashlib
import os
def check_password(tagged_digest_salt, password):
"""
Checks the OpenLDAP tagged digest against the given password
"""
# the entire payload is base64-encoded
assert tagged_digest_salt.startswith('{SSHA}')
# strip off the hash label
digest_salt_b64 = tagged_digest_salt[6:]
# the password+salt buffer is also base64-encoded. decode and split the
# digest and salt
digest_salt = digest_salt_b64.decode('base64')
digest = digest_salt[:20]
salt = digest_salt[20:]
sha = hashlib.sha1(password)
sha.update(salt)
return digest == sha.digest()
def make_secret(password):
"""
Encodes the given password as a base64 SSHA hash+salt buffer
"""
salt = os.urandom(4)
# hash the password and append the salt
sha = hashlib.sha1(password)
sha.update(salt)
# create a base64 encoded string of the concatenated digest + salt
digest_salt_b64 = '{}{}'.format(sha.digest(), salt).encode('base64').strip()
# now tag the digest above with the {SSHA} tag
tagged_digest_salt = '{{SSHA}}{}'.format(digest_salt_b64)
return tagged_digest_salt
if __name__ == '__main__':
# buffer straight out of OpenLDAP
ldap_buf = 'e1NTSEF9VGY1dVFxUkl0VzV2NGowV0RNNXczY2dJd2ZLS0FUcFg='
print 'ldap buffer result: {}'.format(check_password(ldap_buf, 'foobar'))
# check that make_secret() above can properly encode
print 'checking make_secret: {}'.format(check_password(make_secret('foobar'), 'foobar'))
@phihos

This comment has been minimized.

Copy link

@phihos phihos commented Nov 5, 2013

Thank you very much! It works like a charm. I will use it to make a custom password hashing backend for the django framework.

@hansthen

This comment has been minimized.

Copy link

@hansthen hansthen commented Aug 13, 2015

Very nice. Thanks.

@rompic

This comment has been minimized.

Copy link

@rompic rompic commented Aug 24, 2016

print 'ldap buffer result: {}'.format(check_password(ldap_buf, 'foobar')) ought to be
print 'ldap buffer result: {}'.format(check_password(ldap_buf.decode('base64'), 'foobar'))

as otherwise assert tagged_digest_salt.startswith('{SSHA}') fails.

@ahmedbilal

This comment has been minimized.

Copy link

@ahmedbilal ahmedbilal commented Jan 16, 2020

I have to modify it a little bit for Python 3

import base64
def check_password(tagged_digest_salt, password):
    digest_salt_b64 = tagged_digest_salt[6:]
    digest_salt = base64.decodebytes(digest_salt_b64)
    digest = digest_salt[:20]
    salt = digest_salt[20:]

    sha = hashlib.sha1(password.encode('utf-8'))
    sha.update(salt)

    return digest == sha.digest()
@sophialiyun

This comment has been minimized.

Copy link

@sophialiyun sophialiyun commented Apr 17, 2020

**Hello, I have to modify

1-def make_secret(password):
2-def check_password(tagged_digest_salt, password):**

"base64"-- This seems to be the encoding method of the ldap password.
These codes can help you use Python to operate the ldap system.

pass_encrypt

check_password

check_password_result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.