In this article
- 01 — An offline attack is a different experiment
- 02 — Hashes are not encrypted passwords
- 03 — Dictionaries, patterns and exhaustive search
- 04 — Search-space arithmetic comes before speed
- 05 — CPU, GPU and Hybrid do real work
- 06 — An estimate is not a promised finding time
- 07 — Real password storage should make guessing expensive
- 08 — Try it without confusing the conclusions
- 09 — Use the experiment to improve real habits
- Sources and further reading
I wanted this experiment to answer a question that a password-strength meter cannot answer on its own: what does your computer actually do when it tries password candidates? A green bar and an impressive number of years are easy to draw. Generating a candidate, calculating its hash, comparing it and counting only completed work is much more interesting.
The Password Cracking Lab does that work locally. You choose an invented password, a search strategy and CPU, GPU or Hybrid mode. Your browser hashes the target, and separate workers try to recover it without receiving the original text. There is no password upload and no pretend cracking animation. If you stop before a match, that is the result.
01 — An offline attack is a different experiment
When you sign in to a website, the service decides whether an attempt is allowed. It can delay repeated failures, limit requests, require a second factor or lock a session. An offline attacker who has obtained a password hash can instead test guesses against that hash without asking the login service for permission each time.
That difference is the starting point for this lab. It deliberately creates a fast, unsalted SHA-256 hash of your fictional target inside your browser. The workers enumerate guesses against that local teaching hash. They do not connect to an account, bypass a login screen, download breached databases or probe a remote computer.
A successful recovery here does not mean someone can sign in to your bank with the same technique. Conversely, MFA does not make a leaked password hash impossible to guess. It can add an independent requirement at the actual login. Offline storage protection and online account protection address different parts of the problem.
02 — Hashes are not encrypted passwords
Encryption is designed to be reversed by someone holding the appropriate key. A cryptographic hash produces a fixed-size digest and has no decryption key. SHA-256 produces 256 bits whether its input is a short word or a long message. Finding a password candidate is not the same operation as decrypting that digest.
For each candidate, the experiment calculates SHA-256 and compares all eight digest words with the target. If they match, the coordinator regenerates that indexed candidate and checks it independently on the CPU and with Web Crypto. Only then does the interface announce recovery. It never compares guesses directly with the original password.
The crucial question is therefore not “can I reverse 256 bits?” It is “how many plausible inputs must I try, and how expensive is each attempt?” A strong hash does not turn a small, predictable input space into a large one. The enormous space of possible SHA-256 outputs is not the space of three-digit passwords.
03 — Dictionaries and genuine blind search
The lab offers four independent methods: German dictionary, English dictionary, Common passwords & IT, and Brute Force. German and English are enabled by default; Common/IT and Brute Force are optional. The German collection has 213,096 base entries (211,575 words and 1,521 word combinations); English has 249,223 (247,725 words and 1,498 word combinations). Names, place names and international computing terms deliberately overlap. Website language does not select a dictionary.
Each selected collection has fixed transformations: original, Title case, UPPERCASE and two whole-word leetspeak forms with the same case transformations. Duplicate bases are removed within each phase. The search checks all selected base collections first, then years 1984–2035, then one-digit and two-digit suffixes including leading zeroes. This produces 1,729,310 German and 2,072,347 English transformed bases; together all dictionary phases require 619,670,091 actual hash checks.
Brute Force then enumerates every combination of all 95 printable ASCII characters including space, beginning at length 1 and continuing through length 24. There is no shortened numeric space, target-derived length or character set. Entered plaintext is used only to create the local SHA-256 target hash.
penis is part of the fixed bundled anatomy vocabulary. sommer2024 can be recovered through the German word and fixed year phase. A1h5 belongs to the Brute-Force space, where the search must genuinely check every preceding combination. Examples do not determine priority or guarantee success. Identical method choices create an identical search plan regardless of the password. Exhaustion or a stopped run is no strength certificate.
The larger German dictionary adds 210,000 selected words from enz/german-wordlist (CC0) to the teaching vocabulary. Selection favours short words, ordered by length then alphabetically; it does not claim to cover every German word. English adds eligible headwords from the official SCOWL/ESDB US dictionary 2026.02.25, with the explicit Hunspell prefix/suffix rules expanded at build time. The licensed ESDB 2026.02.25 selection through level 80 adds US/GB/Canada spellings, including less frequent valid words and curated everyday vocabulary. Both sources are transliterated and deduplicated for the documented ASCII search space.
The new “Common passwords & IT” checkbox contains 26,652 bases from the public SecLists Common-Credentials list and fixed computing vocabulary, expanded with curated names, films, games, hobbies and 15,000 first names from aggregated SSA statistics (US public domain). No new leaked credentials were imported. This is a published test list, not a current popularity statistic. When selected, its phases precede DE and EN. With the fixed transformations and suffixes it requires 34,499,439 actual hash checks. Larger dictionaries improve coverage while increasing work and memory use. The source snapshots and processing are documented.
04 — Search-space arithmetic comes before speed
For a fixed length L and an alphabet containing A characters, the exhaustive space contains A^L candidates. If multiple lengths are enabled, their spaces are added. Leading zeroes matter: 007 is a three-character candidate, distinct from 7.
Year rules now begin at 1984 and run through at least 2035; after 2035 the upper bound follows the calendar year, limited to four digits. Familiar names such as Bud Spencer and German compounds belong to a fixed curated selection. Candidates are never derived from entered plaintext. A missing dictionary match does not prove security.
| Search | Hash checks | Coverage |
|---|---|---|
| German dictionary with fixed patterns | 281,877,530 | 1,729,310 transformed bases × 163 |
| English dictionary with fixed patterns | 337,792,561 | 2,072,347 transformed bases × 163 |
| Both dictionaries | 619,670,091 | Overlapping phases count as actual hash checks |
| Brute Force, length 1 | 95 | All printable ASCII characters |
| Brute Force, lengths 1–24 | Σ 95n, n = 1…24 | Very large finite space |
These are search counts, not measured cracking speeds. A person-chosen password is also not necessarily uniform over its nominal character set. Choosing a familiar name and appending a date creates a different guessing problem from generating a unique random password of the same length.
The lab keeps indices and totals as JavaScript BigInt values. That matters when a space exceeds the largest exactly representable ordinary JavaScript integer. The display may round a percentage or duration, but candidate indexing and completed-range accounting remain exact.
05 — CPU, GPU and Hybrid do real work
CPU mode uses dedicated Web Workers, keeping candidate generation and hashing off the main interface thread. You can limit worker count and computational intensity. More workers can increase throughput, but also compete with the rest of your computer. A laptop running on battery deserves a different setting from an idle desktop.
GPU mode first tries WebGPU in a worker. If that context cannot initialize, it independently tries the main thread, preparing candidates in a separate worker and submitting real GPU work asynchronously. Adapter requests try high-performance, default and compatibility feature levels; browser support still determines what is available. The selected path and precise failure stage are shown in the expandable diagnostics. A usable path requests a device, compiles a WGSL compute shader and runs actual SHA-256 rounds in parallel. Each invocation checks one encoded candidate. The browser still has to prepare input buffers, upload them, schedule the shader and retrieve its answer. All of that is part of the practical cost.
The GPU is not guaranteed to win. Small batches, transfer overhead, browser scheduling, the selected adapter and the rest of your workload can change the result. This lab measures completed work instead of displaying a fixed “GPU multiplier.” Software-only adapters are disabled in the normal interface, and unavailable WebGPU disables both GPU and Hybrid mode.
Hybrid mode runs CPU workers concurrently with the selected GPU execution path. One shared coordinator assigns different indexed ranges to each engine and hands out more work as an engine completes a batch. Neither engine silently switches into the other mode. A lost GPU ends the run with an explicit error rather than reporting subsequent CPU work as GPU performance.
Candidate preparation for the GPU still uses a worker's CPU; “GPU” means the SHA-256 candidate checks execute in the shader. That distinction is useful when interpreting small-search results or comparing this browser exercise with mature native tools such as John the Ripper.
06 — An estimate is not a promised finding time
Before an attack, the lab warms up the engines separately and measures actual batches. It divides the configured candidate count by measured throughput to estimate a complete traversal. During the attack, measured results update that estimate. No three-second success sequence or invented hardware rate is built in.
The location of a matching candidate is unknown to the search engine. It might be near the beginning, near the end, or outside the space entirely. Dividing the space by two would only describe an expected position under additional assumptions; it would not tell us when your particular invented password will be found.
Changing the password alone therefore does not necessarily change the initial full-search estimate. With the same configuration, you are asking the machine to traverse the same space. Predictable names and suffixes become cheap only when an appropriate strategy places those candidate patterns early.
Calibration counts are separate from attack counts. Warm-up is excluded from the measured calibration counter. CPU and GPU calibration contributions share one real wall-time window, including intensity rests, so their sum represents the measured combined rate. During an attack, current rates use completed candidates in a rolling wall-time window; the final average uses confirmed attempts divided by elapsed attack time.
All dispatched candidates in a completed batch count, even if one lane found a match. Other engines may already be processing their own ranges. The counter does not pretend every worker stopped at the exact instant of the first matching hash. Initialization, calibration, deliberate pauses and final independent verification are excluded from attack elapsed time.
07 — Real password storage should make guessing expensive
SHA-256 is deliberately fast. That is useful for many cryptographic tasks, but an unsuitable property for password storage on its own. Our teaching hash deliberately removes the expensive parts so visitors can observe real searches without waiting for a production password-storage workload.
A unique salt distinguishes each stored password hash and prevents one precomputed lookup from applying identically to every account. It does not turn a predictable password into an unpredictable one or prevent guesses against an individual known hash.
Modern password hashing such as Argon2id adds configurable computation and memory cost. Those costs affect how many guesses an attacker can process simultaneously. A fast SHA-256 rate from this lab is not an Argon2id cracking rate, and there is no honest universal conversion factor between the two.
When building an application, use a maintained password-hashing implementation and current storage guidance, then choose suitable parameters for your service. This exhibit explains the distinction; it does not provide a production password-storage design.
08 — Try it without confusing the conclusions
- Open the lab, enter an invented password and choose CPU, GPU or Hybrid. Begin with conservative device load.
- Compare the same invented word, such as
penis, with dictionaries and then Brute Force alone. Checkboxes change only the predetermined search space. - Compare
sommer2024andA1h5. Watch the selected methods, current phase, real attempts per second and verified match time. Brute Force offers no guaranteed quick result. - Try a dictionary alone against an invented value outside its patterns. Only full exhaustion produces “not found in the selected search space”.
- Compare available hardware modes using the same method choices. Calibration runs automatically on Start. Pause retains the session, Stop ends it and Reset clears the local result.
A longer search has no automatic demo cutoff. Pause waits for assigned batches to complete and preserves the in-memory session. Resume continues from the same ledger. Stop ends the computation, and Reset clears the target-related session and any revealed result.
The page pauses a running search when the tab is hidden. A closed, suspended or throttled browser is not a reliable background compute service. Long runs also consume energy and produce heat; choose conservative settings on phones and laptops. Brute-force candidates are ASCII, 1–24 characters; dictionary patterns can reach 24 ASCII characters. Input is hashed exactly as UTF-8 without normalization. That explicit boundary matters more than a reassuring short-run result.
Have a real encrypted ZIP, RAR, 7Z or PDF file whose password you forgot? That is a different problem from this SHA-256 teaching experiment. My Archive Recovery Lab checks supported encrypted files locally in your browser, verifies recovered contents and provides downloads without uploading the selected file. Use it only for files you own or are authorized to access; CPU is the default, while supported ZIP/RAR5 variants can also use manual WebGPU/Hybrid mode.
09 — Use the experiment to improve real habits
A password manager helps you generate and keep unique passwords instead of inventing predictable variations of one base word. Reuse creates a separate risk: a credential exposed at one service can be tried at another without anybody needing to crack a fresh hash.
Passkeys can replace shared password secrets for supporting services, and appropriately implemented authentication can resist phishing. Where passwords remain, use unique generated credentials and enable a suitable second factor. Protect recovery channels and the device holding your credentials too.
The useful lesson is the relationship between search order, input predictability, hash cost and measured hardware performance. A short successful recovery demonstrates one real comparison process. An unsuccessful run tells us only what that process actually checked. That is a better foundation than a green “secure” label.
Sources and further reading
The experiment's implementation and limits are documented in the repository. These primary references cover the hash, browser APIs and password-storage distinctions discussed here.