1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
=======================================================================
:class:`passlib.hash.crypt16` - Crypt16, a des-crypt variant
=======================================================================
.. currentmodule:: passlib.hash
This class implements Crypt16 (a modified version of des-crypt) commonly
found on Ultrix and Tru64. It's a minor modification of :class:`~passlib.hash.des_crypt`,
which allows passwords of up to 16 characters.
.. warning::
This algorithm is dangerously weak, and should not be used for new applications.
Not only does it suffer from all of the flaws of :class:`~passlib.hash.des_crypt`,
but it reveals information about password length and content.
.. note::
This format is frequently confused with :class:`~passlib.hash.bigcrypt`,
another (weak) derivative of des-crypt, because bigcrypt
will have hash strings of the same size and charset
for passwords between 9 and 16 chars in length.
Usage
=====
This class can be used in exactly the same manner as :class:`~passlib.hash.des_crypt`.
Functions
=========
.. autoclass:: crypt16
Format
======
An example hash (of ``passphrase``) is ``aaX/UmCcBrceQ0kQGGWKTbuE``.
A crypt16 hash string has the format ``{salt}{checksum_1}{checksum_2}``, where:
* ``{salt}`` is the salt, stored as a 2 character :func:`hash64 <passlib.utils.h64.encode_int12>`-encoded
12-bit integer (``aa`` in the example).
* each ``{checksum_i}`` is a separate checksum, stored as an 11 character
:func:`hash64 <passlib.utils.h64.encode_dc_int64>`-encoded 64-bit integer (``X/UmCcBrceQ`` and ``0kQGGWKTbuE``
in the example).
Algorithm
=========
The crypt16 algorithm uses a weakened version of the des-crypt algorithm:
1. given a password and a 12-bit salt...
2. first the password is null-padded or truncated to 16 characters, as needed.
3. then a 56-bit DES key is generated from the lower 7 bits of the first 8 characters of the password.
4. the first checksum is generated by :func:`des encrypting <passlib.utils.des.mdes_encrypt_int_block>`
a 64-bit input block of null data for 20 rounds, using the DES key from step 3,
and the 12-bit salt from step 1.
5. the 64-bit DES output block is :func:`hash 64 <passlib.utils.h64.encode_dc_int64>`-encoded
to create the first checksum segment.
6. the second checksum is generated by running the 2nd set of 8 characters of the password
through steps 3..5; except that the des-encryption step uses the same salt but only 5 rounds.
The smaller number of rounds makes this slightly weaker than des-crypt,
but is *much* weaker for passwords under 9 characters, as well
as the fact that the two checksums can be attacked at once,
since they use the same salt value.
Deviations
==========
This implementation of crypt16 deviates from public document of the format in one way:
* Before generating a hash, PassLib encodes unicode passwords using UTF-8.
The original bigcrypt was designed for 7-bit us-ascii, so this should not
conflict with most existing hashes. As of this writing, the authors
know of no specification defining the official behavior that should be used
in this situtation.
References
==========
* `<http://www.mail-archive.com/exim-dev@exim.org/msg00970.html>`_ - discussion of bigcrypt & crypt16
|