diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2020-02-16 10:56:06 -0500 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2020-02-16 10:56:06 -0500 |
| commit | 2766485f5760489fedb2e73f8a162c83633bbbcb (patch) | |
| tree | 7c62d5d273f5bfd1082ab46c6f436a9447c3bdd1 /docs/lib | |
| parent | ec62db38788b1dc0c8f78060f6119cb63bbacfbd (diff) | |
| download | passlib-2766485f5760489fedb2e73f8a162c83633bbbcb.tar.gz | |
passlib.hash.bcrypt_sha256: now uses hmac-sha256 instead of plain sha256
(fixes issue 114)
Diffstat (limited to 'docs/lib')
| -rw-r--r-- | docs/lib/passlib.hash.bcrypt.rst | 2 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.bcrypt_sha256.rst | 39 |
2 files changed, 27 insertions, 14 deletions
diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst index 0d7319c..436148c 100644 --- a/docs/lib/passlib.hash.bcrypt.rst +++ b/docs/lib/passlib.hash.bcrypt.rst @@ -124,7 +124,7 @@ Security Issues and only the first 72 bytes of a password are hashed... all the rest are ignored. Furthermore, bytes 55-72 are not fully mixed into the resulting hash (citation needed!). To work around both these issues, many applications first run the password through a message - digest such as SHA2-256. Passlib offers the premade :doc:`passlib.hash.bcrypt_sha256` + digest such as (HMAC-) SHA2-256. Passlib offers the premade :doc:`passlib.hash.bcrypt_sha256` to take care of this issue. Deviations diff --git a/docs/lib/passlib.hash.bcrypt_sha256.rst b/docs/lib/passlib.hash.bcrypt_sha256.rst index 20ef5ab..a3035b1 100644 --- a/docs/lib/passlib.hash.bcrypt_sha256.rst +++ b/docs/lib/passlib.hash.bcrypt_sha256.rst @@ -10,7 +10,7 @@ BCrypt was developed to replace :class:`~passlib.hash.md5_crypt` for BSD systems It uses a modified version of the Blowfish stream cipher. It does, however, truncate passwords to 72 bytes, and some other minor quirks (see :ref:`BCrypt Password Truncation <bcrypt-password-truncation>` for details). -This class works around that issue by first running the password through SHA2-256. +This class works around that issue by first running the password through HMAC-SHA2-256. This class can be used directly as follows:: >>> from passlib.hash import bcrypt_sha256 @@ -18,11 +18,11 @@ This class can be used directly as follows:: >>> # generate new salt, hash password >>> h = bcrypt_sha256.hash("password") >>> h - '$bcrypt-sha256$2a,12$LrmaIX5x4TRtAwEfwJZa1.$2ehnw6LvuIUTM0iz4iz9hTxv21B6KFO' + '$bcrypt-sha256$v=2,t=2b,r=12$n79VH.0Q2TMWmt3Oqt9uku$Kq4Noyk3094Y2QlB8NdRT8SvGiI4ft2' >>> # the same, but with an explicit number of rounds >>> bcrypt_sha256.using(rounds=13).hash("password") - '$bcrypt-sha256$2b,13$Mant9jKTadXYyFh7xp1W5.$J8xpPZR/HxH7f1vRCNUjBI7Ev1al0hu' + '$bcrypt-sha256$v=2,t=2b,r=13$AmytCA45b12VeVg0YdDT3.$IZTbbJKgJlD5IJoCWhuDUqYjnJwNPlO' >>> # verify password >>> bcrypt_sha256.verify("password", h) @@ -46,25 +46,38 @@ Bcrypt-SHA256 is compatible with the :ref:`modular-crypt-format`, and uses ``$bc for all it's strings. An example hash (of ``password``) is: - ``$bcrypt-sha256$2a,12$LrmaIX5x4TRtAwEfwJZa1.$2ehnw6LvuIUTM0iz4iz9hTxv21B6KFO`` + ``$bcrypt-sha256$v=2,t=2b,r=12$n79VH.0Q2TMWmt3Oqt9uku$Kq4Noyk3094Y2QlB8NdRT8SvGiI4ft2`` -Bcrypt-SHA256 hashes have the format :samp:`$bcrypt-sha256${variant},{rounds}${salt}${checksum}`, where: +Version 1 of this format had the format :samp:`$bcrypt-sha256${type},{rounds}${salt}${digest}`. +Passlib 1.7.3 introduced version 2 of this format, which changed the algorithm slightly (see below), +and adjusted the format to indicate a version: :samp:`$bcrypt-sha256$v=2,t={type},r={rounds}${salt}${digest}`, where: -* :samp:`{variant}` is the BCrypt variant in use (usually, as in this case, ``2a``). +* :samp:`{type}` is the BCrypt variant in use (always ``2b`` under version 2; though ``2a`` was allowed under version 1). * :samp:`{rounds}` is a cost parameter, encoded as decimal integer, which determines the number of iterations used via :samp:`{iterations}=2**{rounds}` (rounds is 12 in the example). -* :samp:`{salt}` is a 22 character salt string, using the characters in the regexp range ``[./A-Za-z0-9]`` (``LrmaIX5x4TRtAwEfwJZa1.`` in the example). -* :samp:`{checksum}` is a 31 character checksum, using the same characters as the salt (``2ehnw6LvuIUTM0iz4iz9hTxv21B6KFO`` in the example). +* :samp:`{salt}` is a 22 character salt string, using the characters in the regexp range ``[./A-Za-z0-9]`` (``n79VH.0Q2TMWmt3Oqt9uku`` in the example). +* :samp:`{digest}` is a 31 character digest, using the same characters as the salt (``Kq4Noyk3094Y2QlB8NdRT8SvGiI4ft2`` in the example). Algorithm ========= The algorithm this hash uses is as follows: * first the password is encoded to ``UTF-8`` if not already encoded. -* then it's run through SHA2-256 to generate a 32 byte digest. -* this is encoded using base64, resulting in a 44-byte result - (including the trailing padding ``=``). For the example ``"password"``, - the output from this stage would be ``"XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg="``. + +* the next step is to hash the password before handing it off to bcrypt: + + - Under version 2 of this algorithm (the default as of passlib 1.7.3), the password is run + through HMAC-SHA2-256, with the HMAC key set to the bcrypt salt (encoded as a 22 character ascii salt string). + + - Under the older version 1 of this algorithm, the password was instead run through plain SHA2-256. + + In either case, this generates a 32 byte digest. + +* this hash is then encoded using base64, resulting in a 44-byte result + (including the trailing padding ``=``). For the example ``"password"`` and the salt ``"n79VH.0Q2TMWmt3Oqt9uku"``, + the output from this stage would be ``b"7CwRr5rxo2JZcVmSDAi/2JPTkvkAdNy20Cz2LwYC0fw="`` (for version 2). + * this base64 string is then passed on to the underlying bcrypt algorithm as the new password to be hashed. See :doc:`passlib.hash.bcrypt` for details - on it's operation. + on it's operation. For the example in the prior line, the resulting + bcrypt digest component would be ``"Kq4Noyk3094Y2QlB8NdRT8SvGiI4ft2"``. |
