4

Do you know how to create a ldap compatible password (preferred md5crypt) via python on Windows

I used to write something like this in Linux but the crypt module is not present on Windows

char_set = string.ascii_uppercase + string.digits
salt = ''.join(random.sample(char_set,8))
salt = '$1$' + salt + '$'
pwd = "{CRYPT}" + crypt.crypt(str(old_password),salt)
giskard
  • 698
  • 1
  • 7
  • 11
  • 1
    You don't. You configure OpenLDAP or whatever your LDAP server is to hash the password itself, and you always provide the password in plaintext via LDAPS, i.e. LDAP over SSL. LDAP will do the necessary hashing when both storing and comparing for login purposes. – user207421 Jun 04 '19 at 04:33

4 Answers4

4

The Passlib python library contains cross-platform implementations of all the crypt(3) algorithms. In particular, it contains ldap_md5_crypt, which sounds like exactly what you want. Here's how to use it (this code will work on windows or linux):

from passlib.hash import ldap_md5_crypt

#note salt generation is automatically handled
hash = ldap_md5_crypt.encrypt("password")

#hash will be similar to '{CRYPT}$1$wa6OLvW3$uzcIj2Puf3GcFDf2KztQN0'

#to verify a password...
valid = ldap_md5_crypt.verify("password", hash)

I should note that while MD5-Crypt is widely supported (Linux, all the BSDs, internally in openssl), it's none-the-less not the strongest hash available really horribly insecure, and should be avoided if at all possible. If you want the strongest hash that's compatible with linux crypt(), SHA512-Crypt is probably the way to go. It adds variable rounds, as well as some other improvements over MD5-Crypt internally.

Eli Collins
  • 8,375
  • 2
  • 34
  • 38
  • MD5 is not just "not the strongest hash", it is almost literally the weakest hash. It has been absolutely broken for many years at this point, and if standards compliance mode is enabled in OpenSSL or Python, then `hashlib` MD5 itself will be unavailable. [Because it's that bad](https://hashtoolkit.com/decrypt-md5-hash/c822c1b63853ed273b89687ac505f9fa), allowing collisions and difficulty reduction techniques. (Noting that that site doesn't "decrypt" them so much as look known hashes up.) It's "widely supported", but also widely known to be less than secure, and widely explicitly disabled. – amcgregor Jun 07 '19 at 11:56
  • As of 2019, "not the strongest hash" is definitely an understatement. I agree, **it's really bloody awful** (only DES-crypt is worse, and that's not saying much!). Passlib already marks this hash as "historical use only". I do want to note that MD5-Crypt uses 1000 rounds of MD5 internally, so that "decrypt md5" site won't work for reversing MD5-Crypt hashes; though crackers like JohnTheRipper make mincemeat of it. – Eli Collins Jun 07 '19 at 14:13
  • Reverse lookup of multiply hashed values won't be effective except to find a collision for that final round. However, MD5 is one of the most efficient hashing algorithms available on my system. OpenSSL (by CPU!) can process (`openssl speed md5`) **72.3 million** MD5 hashes per second; John the Ripper would certainly make quick work of them. At 1000 rounds… that's still 23.7K attempts per second. A 6-character reasonably complex password might offer as many as 735,091,890,625 combinations, or just over 10,000 seconds (2.8 hours) to break, worst-case. Yes, it's that bad. (GPU or FPGA is worse.) – amcgregor Jun 07 '19 at 14:29
3

From here http://www.openldap.org/faq/data/cache/347.html

One of the variants for generating SHA-hash can be:

import sha 
from base64 import b64encode 

ctx = sha.new("your_password") 
hash = "{SHA}" + b64encode(ctx.digest())
print(hash)

This code is for Python.

# python my_sha.py
{SHA}Vk40DNSEN9Lf6HbuFUzJncTQ0Tc=

I (and not only me) don't recommend to use MD5 anymore.

PS. Follow the link you can try some windows variants.

ipeacocks
  • 2,187
  • 3
  • 32
  • 47
  • 1
    Apologies for the necrobump, but I feel it important to point out that this approach (using an [unsalted hash](https://en.wikipedia.org/wiki/Salt_(cryptography))) is dangerous and insecure. It's not just "don't use [MD5](https://en.wikipedia.org/wiki/MD5#Security)" (which can be fine for light data integrity purposes, still!), it's "[don't use unsalted hashes](https://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right)", too. – amcgregor Dec 30 '19 at 15:41
1

You'll want to use fcrypt, which is a pure Python implementation of the Unix module crypt. It's a bit slower than crypt but it has the same functionality.

Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
  • fcrypt only supports the original DES crypt algorithm, it doesn't support any of the later `$x$` formats which were added in, such as md5crypt. – Eli Collins May 06 '11 at 16:10
0

Disclaimer: I know Google, not cryptography.

From the crypt docs:

This module implements an interface to the crypt(3) routine, which is a one-way hash function based upon a modified DES algorithm; see the Unix man page for further details. Possible uses include allowing Python scripts to accept typed passwords from the user, or attempting to crack Unix passwords with a dictionary.

You could have a look at md5crypt.py. Alternatively, crypt for Windows is part of GnuWin32. Here's some of the Unix man page; the Windows interface should be similar.

CRYPT(3) Linux Programmer's Manual
CRYPT(3)

NAME crypt, crypt_r - password and data encryption

SYNOPSIS

   #define _XOPEN_SOURCE
   #include <unistd.h>

   char *crypt(const char *key, const char *salt);

   char *crypt_r(const char *key, const char *salt,
                 struct crypt_data *data);

Link with -lcrypt.

DESCRIPTION

crypt() is the password encryption function. It is based on the Data Encryption Standard algorithm with variations intended (among other things) to discourage use of hardware implementations of a key search.

key is a user's typed password.

salt is a two-character string chosen from the set [a–zA–Z0–9./]. This string is used to perturb the algorithm in one of 4096 different ways.

By taking the lowest 7 bits of each of the first eight characters of the key, a 56-bit key is obtained. This 56-bit key is used to encrypt repeatedly a constant string (usually a string consisting of all zeros). The returned value points to the encrypted password, a series of 13 printable ASCII characters (the first two characters represent the salt itself). The return value points to static data whose content is overwritten by each call.

Warning: The key space consists of 2**56 equal 7.2e16 possible values. Exhaustive searches of this key space are possible using massively par‐ allel computers. Software, such as crack(1), is available which will search the portion of this key space that is generally used by humans for passwords. Hence, password selection should, at minimum, avoid common words and names. The use of a passwd(1) program that checks for crackable passwords during the selection process is recommended.

The DES algorithm itself has a few quirks which make the use of the crypt() interface a very poor choice for anything other than password authentication. If you are planning on using the crypt() interface for a cryptography project, don't do it: get a good book on encryption and one of the widely available DES libraries.

Katriel
  • 120,462
  • 19
  • 136
  • 170