Navigation

As of 2012-6-7, this algorithm is “no longer considered safe”
by its author [4], citing the increased
speed of the MD5 hash on modern hardware, and MD5-Crypt’s
lack of a variable time-cost parameter. See Passlib’s
recommended hashes for a replacement.

This algorithm was developed for FreeBSD in 1994 by Poul-Henning Kamp,
to replace the aging passlib.hash.des_crypt.
It has since been adopted by a wide variety of other Unix flavors, and is found
in many other contexts as well. Due to its origins, it’s sometimes referred to as “FreeBSD MD5 Crypt”.
Security-wise it should now be considered weak,
and most Unix flavors have since replaced it with stronger schemes
(such as sha512_crypt and bcrypt).

This is also referred to on Cisco IOS systems as a “type 5” hash.
The format and algorithm are identical, though Cisco seems to require
4 salt characters instead of the full 8 characters
used by most systems [3].

salt (str) – Optional salt string.
If not specified, one will be autogenerated (this is recommended).
If specified, it must be 0-8 characters, drawn from the regexp range [./0-9A-Za-z].

salt_size (int) – Optional number of characters to use when autogenerating new salts.
Defaults to 8, but can be any value between 0 and 8.
(This is mainly needed when generating Cisco-compatible hashes,
which require salt_size=4).

relaxed (bool) –

By default, providing an invalid value for one of the other
keywords will result in a ValueError. If relaxed=True,
and the error can be corrected, a PasslibHashWarning
will be issued instead. Correctable errors include
salt strings that are too long.

If the round is even, add the previous round’s result to digest C (for round 0, add digest A instead).

If the round is not a multiple of 3, add the salt to digest C.

If the round is not a multiple of 7, add the password to digest C.

If the round is even, add the password to digest C.

If the round is odd, add the previous round’s result to digest C (for round 0, add digest A instead).

Use the final value of MD5 digest C as the result for this round.

Transpose the 16 bytes of the final round’s result in the
following order: 12,6,0,13,7,1,14,8,2,15,9,3,5,10,4,11.

Encode the resulting 16 byte string into a 22 character
hash64-encoded string
(the 2 msb bits encoded by the last hash64 character are used as 0 padding).
This results in the portion of the md5 crypt hash string referred to as checksum in the format section.

It relies on the MD5 message digest, for which theoretical pre-image attacks exist [2].

More seriously, its fixed number of rounds (combined with the availability
of high-throughput MD5 implementations) means this algorithm
is increasingly vulnerable to brute force attacks.
It is this issue which has motivated its replacement
by new algorithms such as bcrypt
and sha512_crypt.

Passlib’s implementation of md5-crypt differs from the reference implementation (and others) in two ways:

Restricted salt string character set:

The underlying algorithm can unambiguously handle salt strings
which contain any possible byte value besides \x00 and $.
However, Passlib strictly limits salts to the
hash64 character set,
as nearly all implementations of md5-crypt generate
and expect salts containing those characters,
but may have unexpected behaviors for other character values.

Unicode Policy:

The underlying algorithm takes in a password specified
as a series of non-null bytes, and does not specify what encoding
should be used; though a us-ascii compatible encoding
is implied by nearly all implementations of md5-crypt
as well as all known reference hashes.

In order to provide support for unicode strings,
Passlib will encode unicode passwords using utf-8
before running them through md5-crypt. If a different
encoding is desired by an application, the password should be encoded
before handing it to Passlib.