WordPress Password Hash Generator

Generate WordPress-compatible password hashes (phpass) and verify existing hashes directly in your browser.

Generate Hash

{{ __t('strength') }} {{ strengthLabel }}
{{ hash }}

Enter a password to generate a WordPress hash.

Verify Hash

{{ verifyResult ? __t('verify_match') : __t('verify_no_match') }}
{{ __t('info_algorithm') }}{{ hashInfo.algorithm }}
{{ __t('info_iterations') }}{{ hashInfo.iterations }}
{{ __t('info_salt') }}{{ hashInfo.salt }}
{{ __t('info_valid_format') }}{{ hashInfo.valid ? '✓' : '✗' }}

What is a WordPress Password Hash?

WordPress uses the phpass (PHPass) library to hash passwords. It employs iterated MD5 hashing with a random salt. The resulting hashes are prefixed with $P$ (or $H$) and are 34 characters long. These hashes are stored in the wp_users table in the user_pass column. While MD5 alone is considered insecure, the many iterations provide additional protection against brute-force attacks.

How does the algorithm work?

The phpass algorithm first generates a random 8-character salt. The hash starts with the prefix $P$, followed by a character indicating the iteration count (e.g., B = 8,192 iterations) and the salt. Then MD5 is applied repeatedly: first to salt + password, then the result is hashed again together with the password — 8,192 times in total. The binary result is then converted to a readable string using a custom base64 encoding. The final hash is always 34 characters long.

Is this tool secure?

Yes. All calculations run entirely in your browser using JavaScript. No passwords or hashes are sent to a server. You can verify this at any time by checking the Network tab in your browser's developer tools.

Common Use Cases

  • Reset a WordPress password directly in the database
  • Verify if a password matches a stored hash
  • Testing and development
  • Migration between WordPress installations

What is inside a phpass hash?

WordPress stores passwords in the wp_users table, column user_pass, in phpass format — a portable PHP password-hashing library written by Solar Designer in 2004 and the WordPress default since 2.5 (2008). A typical hash looks like: $P$BvAY9z5z.bC0FzG3p4rXmQE9YkE7gI/ — 34 chars, starting with $P$ as the phpass marker, followed by the iteration factor (B = 2^13 = 8192 rounds) and an 8-byte salt in phpass's base64 alphabet.

Internally, phpass is an iterated MD5 construction: salt + password is hashed once with MD5, then the binary hash (16 bytes) is concatenated with the password and MD5'd again — 8192 times in a row. The final 22 base64 characters of the last hash are the output. The fact that MD5 is broken as a cryptographic hash function (collision attacks since 2004) does not matter here: password hashing requires preimage resistance, not collision resistance — and preimages on MD5 remain open.

Since WordPress 6.8 (April 2025) the algorithm was extended: WordPress now uses bcrypt (PHP password_hash() with PASSWORD_BCRYPT) for new passwords — recognizable by the $wp$2y$ prefix. Phpass hashes ($P$) are still accepted and transparently migrated to bcrypt on next login. This tool produces $P$ by default for backward compatibility (every WP version 2.5 through 6.x reads it); on 6.8+ they auto-upgrade to $wp$2y$ on first login.

How to reset the password directly in the database

If you have lost admin login and email reset is not available (e.g. broken SMTP), you can write the generated hash directly to the database. Via phpMyAdmin or the MySQL CLI:

-- 1. Generate hash above, e.g.:
-- $P$BvAY9z5z.bC0FzG3p4rXmQE9YkE7gI/

-- 2. Run in the database:
UPDATE wp_users
SET    user_pass = '$P$BvAY9z5z.bC0FzG3p4rXmQE9YkE7gI/'
WHERE  user_login = 'admin';

-- 3. Verify:
SELECT user_login, user_pass FROM wp_users WHERE user_login = 'admin';

-- IMPORTANT: the table prefix may differ from the default 'wp_'
--            (see wp-config.php, variable $table_prefix).

Typical scenarios

You almost always need this tool in one of five situations:

  • Emergency admin reset — the only administrator is locked out, password-reset email never arrives (mail server misconfigured, spam, deleted mailbox). Generate hash, write into wp_users.user_pass via phpMyAdmin, log in. Time: 2 minutes.
  • Staging and test setups from a DB dump — you import the production DB locally and want to log in as any user. Instead of knowing the production password, overwrite the hash for 1-2 test users with a known value (test1234).
  • Migration between WP installations — when transferring users from an old site (e.g. via the User Switching plugin) the hash must be preserved. Use verify mode to check that a known password actually matches the hash before migrating.
  • Custom user provisioning — you write a setup script or bulk importer (e.g. 500 new course participants in a WP-LMS install) and need password hashes that WordPress accepts immediately. Generate them client-side, write via WP-CLI or directly via wp_insert_user().
  • Hash forensics for breach investigation — you analyze a wp_users table from a backup or leaked dump. Drop the hash into verify, try a suspect password (password123, the WP default admin name admin, etc.) and immediately see whether weak credentials were in use.

Security limits and what phpass does not solve

phpass with 8192 MD5 iterations is below the current recommended minimum (OWASP Password Storage Cheat Sheet, NIST SP 800-63B-Rev4 May 2025). Bcrypt with cost=12 or Argon2id with 19 MiB memory and 2 iterations are the current defaults. On an RTX 4090 Hashcat reaches about 80 MH/s against phpass — meaning an 8-char alphanumeric password falls in under an hour. Consequence: the hash is only half the story. If you still run WP sites below 6.8 in 2026, you should (1) plan an upgrade to 6.8+, (2) set admin passwords to at least 16 chars or a 6-word passphrase, (3) install WPS-Hide-Login + Limit-Login-Attempts + a 2FA plugin. This tool is an emergency device, not a security panacea.

Frequently asked questions

Does a $P$ hash still work in WordPress 6.8 and later?
Yes. WordPress 6.8 switched the write side to bcrypt ($wp$2y$) but still accepts all legacy formats on login ($P$, $H$, even pre-2008 unsalted MD5). On first successful login the hash transparently upgrades to $wp$2y$. So even in 6.8+ you can drop a $P$ hash into wp_users.user_pass — the admin logs in, the hash auto-migrates.
Where do I find the wp_users table?
In your WordPress database. The DB name, user and table prefix live in wp-config.php (variables DB_NAME, $table_prefix). Access via phpMyAdmin (provided by your host like All-Inkl, Strato, Hetzner), Adminer, MySQL Workbench or the CLI mysql -u root -p dbname. Caution: in multi-site or renamed installs the wp_ prefix may be wpsite_, blog123_ or a random value.
Does the tool generate a different hash for the same password each time?
Yes — by design. Each phpass hash carries an 8-byte salt freshly drawn from crypto.getRandomValues() on every generation. Hashes for password123 look different on every call. Verify does not care: the salt is encoded inside the hash, verify extracts it and compares in constant time.
Are my passwords sent over the network?
No. The full hash computation runs as JavaScript in the browser tab. There is no backend round-trip, no logging, no analytics that sees the password or hash. You can verify this in DevTools (Network tab) — no request is fired on click of Generate.
What is the difference between $P$ and $H$?
Algorithmically identical. $P$ is the WordPress portable marker, $H$ the phpBB3 marker for the same scheme. You may see $H$ in old forum databases or in plugins attempting cross-compatibility. WordPress reads both but always writes $P$ (in 6.8+, $wp$2y$).
Can I recover the original password from a hash?
Not directly — hash functions are one-way. But Hashcat or John the Ripper can try about 80 MH/s against phpass on a GPU. A 6-char password falls in seconds, 8-char alphanumeric in under an hour, 10-char alphanumeric in a few days. A 6-word Diceware passphrase or 16+ char random password stays practically safe. If you legitimately need to "crack" a forgotten hash (your own site), use the verify function with your candidate list instead of Hashcat — faster and safer.

Related tools