.. index:: django; hash formats ============================================================= :samp:`passlib.hash.django_{digest}` - Django-specific Hashes ============================================================= .. currentmodule:: passlib.hash The `Django `_ web framework provides a module for storing user accounts and passwords (:mod:`!django.contrib.auth`). This module's password hashing code supports a few simple salted digests, stored using the format :samp:`{id}${salt}${checksum}` (where :samp:`{id}` is an identifier assigned by Django). Passlib provides support for all the hashes used by Django: * :class:`django_salted_sha1` - simple salted SHA1 digest, currently Django's default. * :class:`django_salted_md5` - simple salted MD5 digest. * :class:`django_des_crypt` - support for legacy :class:`des_crypt` hashes, shoehorned into Django's hash format. * :class:`hex_md5` - historical format used by old Django versions. .. warning:: All of these hashes are suceptible to brute-force attacks; even the strongest of these (:class:`django_salted_sha1`) is a simple single-round salted digest. They should not be used for any purpose besides manipulating existing Django password hashes. .. seealso:: * :data:`passlib.apps.django_context` - a premade Django context which can read all of the formats listed below. * :mod:`passlib.ext.django` - a plugin that updates Django to use a stronger hashing scheme, and migrates existing hashes as users log in. Salted Hashes ============= Usage ----- These classes can be used directly as follows:: >>> from passlib.hash import django_salted_sha1 as dss >>> #encrypt password >>> h = dss.encrypt("password") >>> h 'sha1$c6218$161d1ac8ab38979c5a31cbaba4a67378e7e60845' >>> lms.identify(h) #check if hash is recognized True >>> lms.identify('JQMuyS6H.AGMo') #check if some other hash is recognized False >>> lms.verify("password", h) #verify correct password True >>> lms.verify("secret", h) #verify incorrect password False Interface --------- .. autoclass:: django_salted_md5() .. autoclass:: django_salted_sha1() Format ------ An example :class:`!django_salted_sha1` hash (of ``password``) is: ``sha1$f8793$c4cd18eb02375a037885706d414d68d521ca18c7`` Both of Django's salted hashes have the same basic format, :samp:`{ident}${salt}${checksum}`, where: * :samp:`{ident}` is an identifier (``sha1`` in the case of the example, ``md5`` for :class:`!django_salted_md5`). * :samp:`{salt}` consists of (usually 5) lowercase hexidecimal digits (``f8793`` in the example). * :samp:`{checksum}` is lowercase hexidecimal encoding of the checksum. The checksum is generated by concatenating the salt digits followed by the password, and hashing them using the specified digest (MD5 or SHA-1). The digest is then encoded to hexidecimal. If the password is unicode, it is converted to ``utf-8`` first. Security Issues --------------- Django's salted hashes should not be considered very secure. * They use only a single round of digests with known collision and pre-image attacks (SHA1 & MD5). * While it could be increased, they currently use only 20 bits of entropy in their salt, which is borderline insufficient to defeat rainbow tables. * They digest the encoded hexidecimal salt, not the raw bytes, increasing the odds that a particular salt+password string will be present in a pre-computed tables of ascii digests. Des Crypt ========= .. autoclass:: django_des_crypt() Format ------ An example :class:`!django_des_crypt` hash (of ``password``) is ``crypt$cd1a4$cdlRbNJGImptk``; the general format is the same as the salted hashes: :samp:`{ident}${salt}${checksum}`, where: * :samp:`{ident}` is the identifier ``crypt``. * :samp:`{salt}` is 5 lowercase hexidecimal digits (``cd1a4`` in the example). * :samp:`{checksum}` is a :class:`!des_crypt` hash (``cdlRbNJGImptk`` in the example). It should be noted that this class essentially just shoe-horns :class:`des_crypt` into a format compatible with the Django salted hashes (above). It has a few quirks, such as the fact that only the first two characters of the salt are used by :class:`!des_crypt`, and they are in turn duplicated as the first two characters of the checksum. For security issues relating to :class:`!django_des_crypt`, see :class:`des_crypt`. Other Hashes ============ .. autoclass:: django_disabled .. note:: Older versions of Django may also have passwords encoded using :class:`~passlib.hash.hex_md5`, though this has been deprecated by Django.