Add support for bcrypt_sha256
Feature request. Add support for this format. It is used by some web frameworks, like CTFd. Python code for the format:
>>> from passlib.hash import bcrypt_sha256
>>> bcrypt_sha256.hash('john')
'$bcrypt-sha256$2b,12$B2bcgGrxCAOZdbU/TDlP6e$8G1QvMXLUpqw1l79lmIRbFMpw1tJwqS'
>>> bcrypt_sha256.verify('john', '$bcrypt-sha256$2b,12$B2bcgGrxCAOZdbU/TDlP6e$8G1QvMXLUpqw1l79lmIRbFMpw1tJwqS')
True
The format internally uses:
bcrypt(base64(sha256_raw($plain)))
bcrypt(base64(sha256_raw($plain))) formula is brought from another implementation: https://github.com/s3inlc/bcrypt-sha256
Some excerpts from passlib's doc (https://passlib.readthedocs.io/en/stable/lib/passlib.hash.bcrypt_sha256.html ):
- New in version 1.6.2.
- BCrypt ... does, however, truncate passwords to 72 bytes, and some other minor quirks (see BCrypt Password Truncation for details). This class works around that issue by first running the password through SHA2-256.
- Changed in version 1.7: Now defaults to "2b" variant.
- $bcrypt-sha256${variant},{rounds}${salt}${checksum}
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=".
- this base64 string is then passed on to the underlying bcrypt algorithm as the new password to be hashed.
As @AlekseyCherepanov found, recent passlib switched to using HMAC-SHA256:
https://passlib.readthedocs.io/en/stable/lib/passlib.hash.bcrypt_sha256.html
Changed in version 1.7.3: For increased security, updated to use HMAC-SHA256 instead of plain SHA256. Now only supports the "2b" bcrypt variant. Hash format updated to “v=2”.
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.
So maybe we'll need to support both versions. And the version with HMAC is more important to support as built-in because it can't conveniently be emulated by pre-hashing a wordlist when targeting multiple hashes.