WordPress Password Hash Generator

Produce the phpass value WordPress writes into user_pass, or test a password against a hash already sitting in your database. Both run through 8192 rounds of MD5 in this tab, with no request leaving your browser.

WordPress password hash console

Leading and trailing spaces are hashed like any other character, so paste carefully.
Eight characters, drawn fresh from the browser crypto source. Change it only when you are reproducing a known hash.
user_pass value
Enter a password and press Generate.
Ready to run

Your reset failed because user_pass is not an MD5

Someone locked out of wp-admin opens phpMyAdmin, sees the MD5 dropdown next to the password field, picks it, saves, and still cannot log in. That dropdown writes a 32 character digest. WordPress has not accepted a bare MD5 as its storage format since version 2.5 in 2008.

What sits in that column is a phpass portable hash: 34 characters starting with $P$, holding a salt and 8192 rounds of MD5 folded over each other. Nothing in phpMyAdmin produces it. MySQL has no function for it either.

The console above does produce it, and writes the UPDATE statement to go with it.

What the 34 characters actually hold

Take a real hash and split it: $P$B12345678Eg2z6eqcenWjcSosVt4mZ.

Two accounts with the same password get different hashes, because the salt differs. That is the point of the salt, and it is also why you cannot copy one user's hash to another user and reason about it as a shared value.

Getting back into a site you own

  1. Try the email reset first. The database route is for cases where mail delivery is broken or the address on the account is dead. Editing rows by hand when you have a working reset link is risk with no return.
  2. Back up the users table. One mysqldump of wp_users takes a second and undoes any mistake in the next four steps.
  3. Generate the hash above and set the table prefix to match your install. The default is wp_, but a hardened site often uses something random, and the statement fails loudly against the wrong name.
  4. Run the UPDATE in phpMyAdmin, Adminer, or the mysql client. Confirm it reports one row changed. Zero rows means the username did not match, and the WHERE clause is case sensitive on most collations.
  5. Log in, then change the password from the profile screen. A password that passed through a browser tool, a clipboard, and a database client has too many copies to keep. WordPress rewrites the row with a fresh salt as soon as you set it properly.

Hosting with WP-CLI available skips all of this: wp user update admin --user_pass="new-password" hashes the value through WordPress itself. Use that when you have shell access.

WordPress 6.8 changed the format, and old hashes still work

Since WordPress 6.8, new passwords are stored with bcrypt at cost 10, prefixed $wp$2y$. The password is run through HMAC-SHA-384 and base64 encoded before bcrypt sees it, which sidesteps the 72 byte input limit bcrypt has always carried.

Existing $P$ hashes were not migrated. WordPress checks them exactly as before and rewrites the row in the new format the next time that user logs in. A phpass hash written today therefore works on 6.8 and on 6.9, and gets replaced on first use rather than rejected.

Generating bcrypt in a browser tab is slow enough to be unpleasant, so this page stops at phpass. If your install is on 6.8 or later and you want the native format, run wp_hash_password() through WP-CLI or a small PHP script on the server.

Reading a prefix you were handed

32 hex characters, no prefix
Bare MD5 from WordPress 2.4 or earlier, or something a plugin or a tutorial wrote by hand. wp_check_password() still accepts these and upgrades the row on the next successful login. The Check tab tests this format too.
$P$B
Standard phpass from WordPress 2.5 through 6.7, and still the value a 6.8 site holds for anyone who has not logged in since the upgrade. 8192 rounds.
$P$ with another letter
Same algorithm at a different round count. Software other than WordPress sets its own cost, and phpass reads the count out of the hash, so a value written at a different cost still validates.
$H$
phpBB3. Byte for byte the same construction. Change the prefix to $P$ and WordPress accepts it, which is how most forum to WordPress migrations carry passwords across.
$wp$2y$10$
WordPress 6.8 or later, bcrypt with the HMAC-SHA-384 pre-hash. Not checkable here.
$2y$10$
Plain bcrypt with no WordPress wrapper. Usually a custom login plugin or a framework sharing the same user table.

Rounds, and why raising them is mostly pointless

The slider goes to 2^17 because the format allows it. Setting it there is close to a waste of time.

8192 rounds of MD5 cost a modern GPU almost nothing. Hashcat mode 400 covers phpass at hundreds of millions of guesses per second on consumer hardware. Doubling the rounds halves the attacker's rate and does the same to your login latency, and you would need roughly a thousandfold increase to reach what bcrypt at cost 10 gives you for free.

There is a practical catch as well. WordPress hardcodes cost 8 in wp_hash_password(), so any row you write at a different count gets rewritten to the default the moment that user logs in. The higher settings on the slider exist for reproducing hashes from other phpass software, not for hardening a WordPress install.

If password storage strength is the real concern, the fix is upgrading to 6.8 for bcrypt, not turning a dial on MD5.

Where this page stops

No cracking. The Check tab confirms one password against one hash, which is what you need to test a migration or confirm a reset worked. Feeding it a candidate list is not something it does.

No bcrypt, in either direction. Neither $wp$2y$ nor $2y$ hashes are generated or verified here. The Check tab identifies them and tells you so rather than reporting a false mismatch.

No file hashing. Earlier versions of this page accepted file uploads, which made no sense for a password field and produced values WordPress would never accept. That path is gone. For file digests use the MD5 Hash Generator or the Hash Generator Suite.

No application passwords. Those live in wp_usermeta, not user_pass, and WordPress hashes them with a fast unsalted scheme because they are long random strings rather than chosen passwords. Different field, different rules.

One accuracy note on the salt: the eight characters come from crypto.getRandomValues where the browser provides it, falling back to Math.random on anything ancient enough to lack it. Any browser from the last decade takes the first path, but the fallback is worth knowing about if you are running something unusual.

Questions that come up mid-reset

The failures people hit between generating a hash and getting back into wp-admin.

I set user_pass with the MD5 function in phpMyAdmin and it still will not log in. Why?

The MD5 dropdown writes 32 hex characters, and WordPress reads that as a legacy pre-2.5 hash. It does accept the format, so the usual cause of failure is something else in the same edit: a trailing space picked up when pasting, the wrong row updated, or an object cache still serving the old user record. Generating a phpass hash above and pasting it as plain text avoids the ambiguity entirely, because that is the format WordPress writes itself.

Why does the same password give a different hash every time I press Generate?

A new salt is drawn on each run, and the salt is mixed in before the first MD5 round. Both hashes are correct and both validate against the same password. To reproduce an exact hash, copy the eight salt characters out of the existing value into the salt field, keep the cost character the same, and the output will match.

Can this recover a password from a hash?

No. The digest is 16 bytes of a one way function and the original text is not in there. Guessing is what recovers passwords, and phpass at 8192 rounds falls quickly to a GPU when the password is a common one. If you are locked out of your own site, reset the row instead. If you are looking at a dump of someone else's users, the answer is to disclose it and rotate every credential.

Does it matter which WordPress version the site runs?

For writing a hash, not much. Every version from 2.5 onward validates a $P$ hash, including 6.8 and later, which check it and then rewrite the row as bcrypt on the next login. What changes is what WordPress produces afterwards, so a site on 6.8 will not keep the phpass value you wrote once the user signs in.

Is 8192 rounds of MD5 still safe in 2026?

It is far better than an unsalted MD5 and well behind current practice. Every hash is individually salted, so precomputed tables are useless and each password has to be attacked on its own. Against a GPU running hashcat mode 400, a dictionary password falls in minutes. That gap is exactly why WordPress moved to bcrypt in 6.8.

Can I move phpBB or Drupal passwords into WordPress?

phpBB3 yes, with a prefix swap. Its $H$ hashes use the same phpass construction, so rewriting the first three characters as $P$ makes them validate under WordPress unchanged. Drupal 7 is a different story: its $S$ hashes run SHA-512 rather than MD5, and no rewrite makes them compatible. Those need a plugin that recognises the old format and re-hashes on first login.

The Check tab says my hash was truncated. What causes that?

A phpass hash is always 34 characters. Shorter values usually come from a copy that clipped the end, from a spreadsheet cell that cut it off, or from a user_pass column narrowed below 255 characters during a botched migration. Widen the column, then reset the affected passwords, because the missing characters are not recoverable from what is left.

Does the password I type get sent anywhere?

No. The MD5 core and the phpass encoding both live in this page script, with no CDN dependency and no network call in the hashing path. Load the page once, disconnect, and everything still works. That said, a password typed into any browser tab has touched your clipboard and your history, so change it from the WordPress profile screen once you are back in.