Note
This algorithm is weak by modern standards, and should not be used in new applications.
This algorithm was developed by BSDi for their BSD/OS distribution. It’s based on des_crypt, and contains a larger salt and a variable number of rounds. This algorithm is also known as “Extended DES Crypt”. It class can be used directly as follows:
>>> from passlib.hash import bsdi_crypt
>>> # generate new salt, encrypt password
>>> hash = bsdi_crypt.encrypt("password")
>>> hash
'_7C/.Bf/4gZk10RYRs4Y'
>>> # same, but with explict number of rounds
>>> bsdi_crypt.encrypt("password", rounds=10001)
'_FQ0.amG/zwCMip7DnBk'
>>> # verify password
>>> bsdi_crypt.verify("password", hash)
True
>>> bsdi_crypt.verify("secret", hash)
False
See also
the generic PasswordHash usage examples
This class implements the BSDi-Crypt password hash, and follows the Password Hash Interface.
It supports a fixed-length salt, and a variable number of rounds.
The encrypt() and genconfig() methods accept the following optional keywords:
| Parameters: |
|
|---|
Changed in version 1.6: encrypt() will now issue a warning if an even number of rounds is used (see Security Issues regarding weak DES keys).
Note
This class will use the first available of two possible backends:
You can see which backend is in use by calling the get_backend() method.
An example hash (of the string password) is _EQ0.jzhSVeUyoSqLupI. A bsdi_crypt hash string consists of a 21 character string of the form _roundssaltchecksum. All characters except the underscore prefix are drawn from [./0-9A-Za-z].
A bsdi_crypt configuration string is also accepted by this module; and has the same format as the hash string, but with the checksum portion omitted.
The checksum is formed by a modified version of the DES cipher in encrypt mode:
Given a password string, a salt string, and rounds string.
The 4 character rounds string is decoded to a 24-bit integer rounds value; The rounds string uses little-endian hash64 encoding.
The 4 character salt string is decoded to a 24-bit integer salt value; The salt string uses little-endian hash64 encoding.
The password is NULL-padded on the end to the smallest non-zero multiple of 8 bytes.
The lower 7 bits of the first 8 bytes of the password are used to form a 56-bit integer; with the first byte providing the most significant 7 bits, and the 8th byte providing the least significant 7 bits. This is the DES key.
For each additional block of 8 bytes in the padded password:
- The current DES key is encrypted using a single round of normal DES, with itself as the input block.
- Step 5 is repeated for the current 8-byte block, and xored against the existing DES key.
Repeated rounds of (modified) DES encryption are performed; starting with a null input block, and using the 56-bit integer from step 5/6 as the DES key.
The salt is used to to mutate the normal DES encrypt operation by swapping bits i and i+24 in the DES E-Box output if and only if bit i is set in the salt value.
The number of rounds is controlled by the value decoded in step 2.
The 64-bit result of the last round of step 7 is then lsb-padded with 2 zero bits.
The resulting 66-bit integer is encoded in big-endian order using the hash64-big format.
BSDi Crypt should not be considered sufficiently secure, for a number of reasons:
This algorithm is none-the-less stronger than des_crypt itself, since it supports variable rounds, a larger salt size, and uses all the bytes of the password.
This implementation of bsdi-crypt differs from others in one way:
Unicode Policy:
The original bsdi-crypt algorithm was designed for 7-bit us-ascii encoding only (as evidenced by the fact that it discards the 8th bit of all password bytes).
In order to provide support for unicode strings, Passlib will encode unicode passwords using utf-8 before running them through bsdi-crypt. If a different encoding is desired by an application, the password should be encoded before handing it to Passlib.
Footnotes
| [1] | Primary source used for description of bsdi-crypt format & algorithm - http://fuse4bsd.creo.hu/localcgi/man-cgi.cgi?crypt+3 |
| [2] | Another source describing algorithm - http://ftp.lava.net/cgi-bin/bsdi-man?proto=1.1&query=crypt&msection=3&apropos=0 |
| [3] | DES weak keys - https://en.wikipedia.org/wiki/Weak_key#Weak_keys_in_DES |