Cryptography

How Hackers Crack Password Hashes: Dictionary, Brute Force, and Rainbow Tables

10 min read
By

Note: This article is for defensive security awareness only.

How Hackers Crack Password Hashes: Dictionary, Brute Force, and Rainbow Tables

Photo by Tima Miroshnichenko from Pexels

When a data breach exposes a database of user accounts, the passwords are usually stored as hashes, not plaintext. A hash is a one-way mathematical function: you can compute the hash from the password, but you cannot reverse it to get the password back. So how do hackers end up with plaintext passwords after a breach?

The answer is that they do not reverse the hash. They guess passwords, hash them, and compare the results to the stolen hashes. If the guessed password produces the same hash as the one in the database, the guess was correct. This is called an offline attack, and it is the primary way password hashes are cracked.

Understanding how this works is essential for building systems that resist these attacks. Let's look at the three main techniques: dictionary attacks, brute force attacks, and rainbow tables.

The Starting Point: A Stolen Database

Before any cracking happens, the attacker needs the hashes. This usually comes from a database breach. The attacker exploits a vulnerability (SQL injection, misconfigured database, insider access, or a backup leak) and exfiltrates the user table.

A typical stolen row looks something like this:

username: alice password_hash: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

That 64-character hex string is a SHA-256 hash. The attacker does not know the password, but they know the hash. Their goal is to find a password that produces this same hash.

The speed at which they can do this depends entirely on the hash function. SHA-256 on a modern GPU can compute roughly 2.5 billion hashes per second. Bcrypt with a cost factor of 12 can compute roughly 3 hashes per second. This difference is the difference between "cracked in seconds" and "not worth attempting."

Dictionary Attacks: Trying Common Passwords

A dictionary attack is the first technique an attacker uses. Instead of trying every possible password, they try a list of the most common passwords. These lists are built from real password databases that have been leaked over the years, and they are remarkably effective.

The most popular password dictionary is the "rockyou" list, which originated from the 2009 breach of RockYou, a company that had 32 million passwords stored in plaintext. Those 32 million real passwords became the foundation for password cracking dictionaries that are still used today.

Modern dictionaries are far more sophisticated. They include:

- Common passwords from every major breach (billions of real passwords) - Variations with numbers and symbols (password1, P@ssw0rd, etc.) - Words from multiple languages - Pop culture references, sports teams, and current events - Patterns (qwerty, 12345678, abcdef) - Leaked passwords from recent breaches, which are the most current

A good dictionary with 10 million entries tested against a SHA-256 hash at 2.5 billion hashes per second takes about 4 milliseconds. In 4 milliseconds, the attacker has found every password in the database that is in the dictionary. For a database of 1 million users, that is 4 seconds total.

This is why "use a strong password" advice matters. If your password is in a dictionary, it does not matter how long it is. It will be found in the first pass.

Brute Force Attacks: Trying Everything

When the dictionary attack fails, the attacker moves to brute force. This means trying every possible combination of characters: a, b, c, ... aa, ab, ac, ... aaa, aab, aac, and so on.

The speed of brute force depends on the character set and the password length:

- Lowercase letters (26 characters): a 6-character password has 26^6 = 308 million combinations. At 2.5 billion SHA-256 hashes per second, that takes 0.12 seconds. - Mixed case + digits (62 characters): a 6-character password has 62^6 = 56.8 billion combinations. At 2.5 billion per second, that takes 22 seconds. - All printable ASCII (95 characters): an 8-character password has 95^8 = 6.6 quadrillion combinations. At 2.5 billion per second, that takes about 26 days.

The key insight is that each additional character multiplies the work. A 6-character password is trivially crackable. An 8-character password with full character set takes weeks. A 12-character password takes millions of years.

This is why password length matters more than complexity. A 16-character password using only lowercase letters (26^16) is harder to brute-force than an 8-character password using all printable characters (95^8). Length wins.

But this all assumes a fast hash function. With bcrypt at cost 12 (3 hashes per second), a 6-character lowercase password takes 308 million / 3 = 102 million seconds, or about 3 years. The hash function changes the calculus entirely.

Rainbow Tables: Precomputed Cracking

A rainbow table is a different approach. Instead of guessing passwords on the fly, the attacker precomputes a massive table of "password to hash" mappings. When they have a stolen hash, they look it up in the table and instantly find the corresponding password.

The advantage of rainbow tables is speed. The lookup is nearly instant, no computation needed. The disadvantage is storage. A rainbow table for all 8-character passwords using lowercase letters is about 500 GB. For all 8-character passwords using full ASCII, it is tens of terabytes.

Rainbow tables use a clever data structure (hash chains with reduction functions) to compress the table, trading some computation at lookup time for much less storage. But the fundamental limitation remains: the table must be precomputed for the specific hash function and, crucially, the specific salt.

This is where salting defeats rainbow tables. If every password is hashed with a unique random salt, the attacker would need a separate rainbow table for every salt. For a database with 1 million users, each with a unique salt, the attacker needs 1 million rainbow tables. This is computationally and storage-wise infeasible.

This is why salting is non-negotiable for password storage. A unique salt per password makes rainbow tables useless and also prevents an attacker from cracking identical passwords in parallel. If two users have the password "summer2026" and the same hash, the attacker only needs to crack it once. With unique salts, they must crack each one independently.

How Modern Hashing Defends Against All Three

The defenses against all three attack types are well understood:

**Use a slow hash function.** Bcrypt, scrypt, and Argon2id are designed to be slow. Each hash computation takes 100-400 milliseconds instead of nanoseconds. This makes dictionary attacks 100 million times slower and brute force attacks impractical for all but the shortest passwords. For a detailed comparison, see our guide on bcrypt vs SHA-256 for password storage.

**Use a unique salt per password.** The salt ensures that even identical passwords produce different hashes. This defeats rainbow tables and prevents parallel cracking of identical passwords. For more on salts, read our guide on what a salt is and why it matters.

**Use a high cost factor.** For bcrypt, a cost factor of 12 or higher makes each hash computation take 400 milliseconds or more. This is fast enough for legitimate logins but slow enough to make large-scale cracking impractical. For a deeper dive, see our bcrypt explained post.

**Encourage long passwords.** Length is the most important factor in password strength. A 16-character password is dramatically harder to brute-force than an 8-character password, even with a smaller character set. Passphrases (multiple words strung together) are an excellent way to achieve length with memorability.

The Economics of Password Cracking

Password cracking is ultimately an economic problem. The attacker has limited resources (hardware, time, electricity) and decides whether cracking your hashes is worth the cost.

With SHA-256 and no salt, cracking is so cheap that any database is worth attacking. With bcrypt at cost 12 and unique salts, cracking a single 8-character password costs hundreds of dollars in compute time. Cracking a database of 1 million users with strong passwords costs more than the data is worth.

This is the goal of password hashing: not to make cracking impossible (it is always theoretically possible), but to make it so expensive that it is not worth attempting. Slow hash functions with unique salts achieve this for all but the most valuable targets.

The Bottom Line

Hackers crack password hashes by guessing passwords, hashing them, and comparing the results. Dictionary attacks find common passwords in seconds. Brute force attacks find any password given enough time. Rainbow tables provide instant lookups but are defeated by salts.

The defense is straightforward: use a slow password hashing function (bcrypt, scrypt, or Argon2id) with a unique salt per password and a high cost factor. This makes dictionary attacks slow, brute force impractical, and rainbow tables useless.

Want to see how password hashing works? Try our password hash generator to hash passwords with different algorithms and see the output in real time. And for a deep dive into the most popular password hashing algorithm, read our bcrypt explained guide.

Frequently Asked Questions

Can hashed passwords be cracked?

Yes. Hashing is a one-way function, but attackers can try hashing candidate passwords and comparing the results to the stolen hash. If they find a password that produces the same hash, they have cracked it. The speed of this process depends on the hashing algorithm. Fast hashes like SHA-256 can be cracked at billions of guesses per second. Slow hashes like bcrypt make this impractical.

What is the difference between a dictionary attack and a brute force attack?

A dictionary attack tries passwords from a precompiled list of common passwords and words. It is fast but only finds passwords that are in the list. A brute force attack tries every possible combination of characters. It is slower but will eventually find any password. Dictionary attacks find most weak passwords quickly. Brute force attacks find strong passwords eventually, but it may take impractically long.

Are rainbow tables still a threat?

Not for properly salted hashes. Rainbow tables are precomputed tables of hash-to-password mappings that allow instant cracking. But they only work when the hash function is unsalted or uses a fixed salt. A unique random salt per password makes rainbow tables useless because the attacker would need a separate table for every possible salt. Modern password hashing functions like bcrypt include salts automatically.

How can I tell if my password hashes are secure?

Check three things: the hashing algorithm, the salt, and the cost factor. Use bcrypt, scrypt, or Argon2id, not MD5, SHA-1, or plain SHA-256. Ensure each password has a unique random salt. For bcrypt, use a cost factor of at least 10 (12 is recommended for 2026). If you are using plain SHA-256, your hashes can be cracked at billions of guesses per second. See our bcrypt vs SHA-256 comparison for details.

Try NovelCrypt Tools

Experience military-grade encryption for your sensitive data. Create self-destructing messages, encrypt files, or explore our experimental lab tools.

Explore NovelCrypt