Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression to find bcrypt hash?

Tags:

regex

hash

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 was found. Bcrypt hash is 60 characters length, and starts with "$2y$".

Example:

$2y$15$nK/B6u765645/lo0867h56546v/BnH5U5g45Aj67u67nMVtrhryt6
like image 492
Jim Avatar asked Jul 14 '15 21:07

Jim


Video Answer


3 Answers

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?

like image 60
Calvin Alvin Avatar answered Oct 07 '22 18:10

Calvin Alvin


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.

like image 31
Wiktor Stribiżew Avatar answered Oct 07 '22 18:10

Wiktor Stribiżew


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
like image 9
d4nyll Avatar answered Oct 07 '22 18:10

d4nyll