Does bcrypt have a maximum password length?

  • I was messing around with bcrypt today and noticed something:

    hashpw('testtdsdddddddddddddddddddddddddddddddddddddddddddddddsddddddddddddddddd', salt)
    Output: '$2a$15$jQYbLa5m0PIo7eZ6MGCzr.BC17WEAHyTHiwv8oLvyYcg3guP5Zc1y'
    
    hashpw('testtdsdddddddddddddddddddddddddddddddddddddddddddddddsdddddddddddddddddd', salt)
    Output: '$2a$15$jQYbLa5m0PIo7eZ6MGCzr.BC17WEAHyTHiwv8oLvyYcg3guP5Zc1y'
    

    Does bcrypt have a maximum password length?

  • Tom Leek

    Tom Leek Correct answer

    8 years ago

    Yes, bcrypt has a maximum password length. The original article contains this:

    the key argument is a secret encryption key, which can be a user-chosen password of up to 56 bytes (including a terminating zero byte when the key is an ASCII string).

    So one could infer a maximum input password length of 55 characters (not counting the terminating zero). ASCII characters, mind you: a generic Unicode character, when encoded in UTF-8, can use up to four bytes; and the visual concept of a glyph may consist of an unbounded number of Unicode characters. You will save a lot of worries if you restrict your passwords to plain ASCII.

    However, there is a considerable amount of confusion on the actual limit. Some people believe that the "56 bytes" limit includes a 4-byte salt, leading to a lower limit of 51 characters. Other people point out that the algorithm, internally, manages things as 18 32-bit words, for a total of 72 bytes, so you could go to 71 characters (or even 72 if you don't manage strings with a terminating zero).

    Actual implementations will have a limit which depends on what the implementer believed and enforced in all of the above. All decent implementations will allow you at least 50 characters. Beyond that, support is not guaranteed. If you need to support passwords longer than 50 characters, you can add a preliminary hashing step, as discussed in this question (but, of course, this means that you no longer compute "the" bcrypt, but a local variant, so interoperability goes down the drain).

    Edit: it has been pointed out to me that although, from a cryptographer's point of view, the article is the ultimate reference, this is not necessarily how the designers thought about it. The "original" implementation could process up to 72 bytes. Depending on your stance on formalism, you may claim that the implementation is right and the article is wrong. Anyway, such is the current state of things that my advice remains valid: if you keep under 50 characters, you will be fine everywhere. (Of course it would have been better if the algorithm did not have a length limitation in the first place.)

    I see. I read an article (here, actually) and it suggested using a server-side key along with the actual password and salt to generate the hash. What would you recommend as the key length, or for this use, should I just hash this first through something like crypt, then bcrypt?

    An additional secret key is often called "peppering". The proper way is to compute a MAC on the password (with HMAC/SHA-256), using the secret key as MAC key; and then use the MAC output as "password" in bcrypt. HMAC/SHA-256 yields 32 bytes, which can be converted to 44 ASCII characters with Base64, within the limit of bcrypt. Moreover, HMAC will process arbitrarily long passwords, so that solves your password length issue as well. Be aware that using a key implies key management issues, which can be tricky (e.g. it interferes with backups and multi-frontend systems).

    Based on some testing just now, the Java bcrypt library jBCrypt has a 72 character limit.

    This is a thought and a question in same time: why not split the password whatever his length, into manageable lengths (72bytes (not 72 character)) and we hash each block with bcrypt, and we join back the results, it can be more longer, it may be ok, or we can hash that too with sha512. it's more slower, but applicable ! what do you think ?

    @TomLeek How's peppering supposed to work when bcrypt apparently rejects passwords containing NUL bytes (which a MAC is as liable to emit as any other)?

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM