Regular expression to find bcrypt hash?

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

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?


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.

Tags:

Hash

Regex