Regular expression to find bcrypt hash?

后端 未结 4 1208
Happy的楠姐
Happy的楠姐 2021-02-12 22:26

I am looking to find bcrypt hash string using regex (in PowerGrep), in a database.

Tried this regex:

{?A-Za-z_0-9.{60}}?

But no match w

相关标签:
4条回答
  • 2021-02-12 22:39

    Use this:

    ^\$2[aby]?\$\d{1,2}\$[.\/A-Za-z0-9]{53}$
    

    Explanation:

    • \$2[aby]?\$ - matches the algorithm used. Valid values are 2, 2a, 2y and 2b
    • \d{1,2}\$ - matches the cost, or how many rounds, which is an integer between 4 and 31 (inclusive)
    • [.\/A-Za-z0-9]{53} - matches the salt and the hash, with the salt making up the first 22 characters, and the hashed password making up the last 31
    0 讨论(0)
  • 2021-02-12 23:00

    Just as an addition to the answer above from @stribizhev. The bcrypt hashes you might encounter out there in the wild come in a few varieties, so you may have to modify the regex to catch all of them. The variations are as follows:

    The "Algorithm Identifier" portion of the hash may include:

    • "2" - the first revision of BCrypt, which suffers from a minor security flaw and is generally not used anymore.

    • "2a" - some implementations suffered from a very rare security flaw.

    • "2y" - format specific to the crypt_blowfish BCrypt implementation, identical to "2a" in all but name.

    • "2b" - latest revision of the official BCrypt algorithm

    ^\$2[ayb]\$.{56}$
    

    seems to work for me

    see here for the breakdown of a bcrypt hash: Can someone explain how BCrypt verifies a hash?

    0 讨论(0)
  • 2021-02-12 23:04

    Update:

    Since beside the y value there might be a or b, you may use

    ^\$2[ayb]\$.{56}$
    

    See the regex demo online. Details:

    • ^ - start of a string
    • \$ - a literal $ char (it should be escaped in a regex pattern to match a literal $ char, else, it will denote the end of string)
    • 2 - a 2 char
    • [ayb] - a character class matching any single char out of the specified set
    • \$ - a $ char
    • .{56} - any 56 chars other than line break chars (if not POSIX compliant regex engine is used, else, it will match any chars; to match any chars in common NFA engines, replace . with [\s\S] or use a corresponding DOTALL flag)
    • $ - end of string.

    Original answer

    Your regex - {?A-Za-z_0-9.{60}}? - contains ranges not inside a character class [...], but inside optional curly braces, and thus they present sequences of literal characters. See your regex demo to see what I mean.

    You can use the following regex:

    ^\$2y\$.{56}$
    

    See demo

    The ^ matches the start of string, \$2y\$ matches $2y$ literally (as $ is a special character and needs escaping) and .{56} is the rest 56 characters.

    0 讨论(0)
  • 2021-02-12 23:04

    According to Wikipedia, bcrypt hashes follow the following format:

    $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
    \__/\/ \____________________/\_____________________________/
     Alg Cost      Salt                        Hash
    

    Where valid values for each segment are:

    • Alg: 2, 2a, 2b, 2x or 2y
    • Cost: 4-31 (zero-padded to 2 digits)
    • Salt: ./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ x 22
    • Hash: ./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ x 31

    Therefore, a comprehensive regex would look something like the following:

    ^[$]2[abxy]?[$](?:0[4-9]|[12][0-9]|3[01])[$][./0-9a-zA-Z]{53}$
    
    0 讨论(0)
提交回复
热议问题