# BCrypt Tables for 6 digit numbers 000000-999999

This is an example of a bcrypt project I am working on. `2a` and `04` are always used and the password is a 6 digit number from 000000 to 999999

Using `2a` and 4 rounds is there a hash table or calculator out there somewhere that shows what the 6 digit number (password) is in this example?

`\$2a\$04\$lzzo9IuiAWyIs2H4NI4w1.KDxgxgUi2h34k9rDaMP/PjEv/WktiMm`

• do you understand what `2a` and `04` mean? Dec 8, 2017 at 10:09
• en.wikipedia.org/wiki/Bcrypt Dec 8, 2017 at 10:10

What you're looking for, in theory, is a thing called a "rainbow table", a lookup table of hashes to their original outputs. There are quite a few of them online (and they tend to be huge, containing far more than the mere million entries for "000000" to "999999"). They're most common for simple hashes (MD5, SHA1, etc.).

Unfortunately for you, bcrypt requires the use of a very standard technique for defeating rainbow tables: a salt that is combined with the password before hashing, meaning the range of passwords you need to check is essentially many orders of magnitude larger than the simple million values you're checking for.

Bcrypt actually requires a salt, so there's definitely one in there. I believe that in your example it is the `lzzo9IuiAWyIs2H4NI4w1.` part (the first 22 base64-encoded characters following the third `\$`, as per Wikipedia's description of the algorithm). The salt has to be stored in plain text, but it means that any rainbow table created without using that specific salt is useless for cracking the output (and no pre-computed table will use that specific random salt).

Somebody could reuse a single salt (with at least some bcrypt implementations, this is possible) but salts are supposed to be generated uniquely for each password. Check whether the first part of the hashes (following the last `\$`) that you want to reverse is different for each value. In any case, the existence of salts at all means a pre-generated rainbow table isn't going to help.

On the other hand, a million entries is a pretty small search space. Bcrypt is a somewhat old password hashing algorithm (notably, it lacks the tunable memory cost parameter that newer functions have, although most people don't have easy access to the hardware that can brute force it most quickly). For simply using a commodity CPU, the difficulty of brute-forcing depends on the "cost" or "work factor" parameter. In your example, this is `04` (the number between the second and third `\$`), which is low by modern standards. You can certainly brute-force any given 6-digit password in under a day (worst-case, that requires just under 12 hashes per second, which should be easy at cost 4). If they aren't using unique salts, this is equivalent to building your own rainbow table and allows reversing all the hashes.

Building a rainbow table just consists of hashing a bunch of inputs (in this case, the full million possibilities), preserving the password < > hash mapping, and sorting by the hash outputs. They can take a while to compute, depending on how slow the hash function is (for a "cost" of 4, pretty quick), how much you can parallelize it (if you have a multi-core machine, each core can work on a different set of passwords; modern CPU caches have no problem with the memory cost of bcrypt), and how many entries you're trying (some rainbow tables have a billion entries; a million is nothing). They also require storage space, but for one table with only a million entries it should take less than 100 MB of storage.

• As far as I remember BCrypt always generates a random salt so technically a generic rainbow table for BCrypt cannot exist. Please correct me if I'm wrong in which case I'd upvote this answer. Also I wouldn't consider BCrypt outdated at all. Dec 8, 2017 at 7:27
• Some implementations auto-generate a salt, but not all of them (though the code samples almost always then call something like `bcrypt.gen_salt()` for the salt param); for example see the NPM (JS) impl: npmjs.com/package/bcrypt. The pseudocode specification of the function takes a salt as input. BCrypt's memory requirement is not tunable (and relatively low); there have been two newer functions that have come out since it was released. Dec 8, 2017 at 8:07
• I can't find any documentation where it is possible to generate bcrypt without a salt (more the opposite in fact). The rest of your answer is a great explanation though. I'd like to remove my downvote and stay "neutral" as I'm only 95% sure of my claims but I can't without an edit to the answer (hell, didn't know about that voting rule) Dec 8, 2017 at 9:07
• Ah, yeah, you do have to have some salt, so I'll edit the answer to explain that. Dec 8, 2017 at 9:36
• @jfrost1121 If you are only trying to crack some specific hashes, even if they all use different salts you should be able to crack each individual one in less than a day's CPU time. Just basically try each possible 6-digit "password" against the stored hash you're currently working on, until you get a match (using the bcrypt verify function, which takes the password and the verifier string that has the cost, salt, and hash). Once you get a match for the first hash, move on to the next hash you want to break, starting over on the password candidates. Dec 10, 2017 at 7:34