Question
I often hear the advice: “Use bcrypt for storing passwords in PHP.”
What exactly is bcrypt, and how is it used in PHP?
PHP does not appear to provide a function literally named bcrypt, and many search results mention Blowfish or old encryption libraries. Since Blowfish is a reversible cipher, that seems confusing when passwords should be stored with a one-way hash, not encrypted in a way that can be decrypted later.
So how does bcrypt relate to password storage in PHP, and what is the correct way to hash and verify passwords?
Short Answer
By the end of this page, you will understand what bcrypt is, why it is suitable for password hashing, and how PHP uses it through password_hash() and password_verify(). You will also learn the difference between hashing and encryption, how salts and cost factors work, and how to avoid common password-storage mistakes.
Concept
bcrypt is a password hashing algorithm designed specifically for storing passwords securely.
Unlike general-purpose hashing functions such as MD5 or SHA-1, bcrypt is intentionally slow. That slowness is a feature: it makes brute-force attacks much more expensive for an attacker.
Why bcrypt matters
When a user creates an account, you should not store the plain password. You also should not “encrypt” it in a reversible way. Instead, you store a hash of the password.
A password hash should have these properties:
- One-way: you can verify a password, but you cannot recover the original password from the hash.
- Salted: each password hash includes a random salt so identical passwords do not produce identical stored values.
- Adaptive: the algorithm should allow you to increase its work factor over time as hardware gets faster.
bcrypt provides these properties.
bcrypt and Blowfish
The confusion often comes from the fact that bcrypt was built using ideas from the Blowfish cipher, but bcrypt itself is not just “encrypting the password with Blowfish.” It is a separate password-hashing scheme.
So while Blowfish is a cipher and reversible when used for encryption, bcrypt is a password hashing function designed for one-way password storage.
How PHP uses bcrypt
In modern PHP, you normally do not call a function named bcrypt directly. Instead, you use:
password_hash($password, PASSWORD_BCRYPT)
and verify with:
Mental Model
Think of password hashing like sealing a word into a special machine that produces a unique stamp.
- You put in the password.
- The machine creates a stamp string.
- You store the stamp.
- Later, if someone gives you a password, you run it through the same type of machine and check whether it matches.
But bcrypt’s machine has two important upgrades:
- It adds a random ingredient called a salt, so the same password does not always create the same output.
- It works deliberately slowly, like a security gate that takes a little time to process each guess.
That delay is tiny for one login, but huge for an attacker trying millions of guesses.
Syntax and Examples
Core syntax
Hash a password
<?php
$password = 'MySecurePassword123!';
$hash = password_hash($password, PASSWORD_BCRYPT);
echo $hash;
Verify a password
<?php
$enteredPassword = 'MySecurePassword123!';
$storedHash = '$2y$10$abcdefghijklmnopqrstuuK5Kx1ZQxVZJz4pA7Yl0QWk4rWkV8wQy';
if (password_verify($enteredPassword, $storedHash)) {
echo 'Password is correct';
} else {
echo 'Invalid password';
}
Recommended modern approach
<?php
$password = 'MySecurePassword123!';
$hash = password_hash($password, PASSWORD_DEFAULT);
PASSWORD_DEFAULT is usually the safest choice because PHP can update the algorithm over time.
Step by Step Execution
Consider this example:
<?php
$password = 'hello123';
$hash = password_hash($password, PASSWORD_BCRYPT);
if (password_verify('hello123', $hash)) {
echo 'Match';
} else {
echo 'No match';
}
Step by step
1. The password is stored in a variable
$password = 'hello123';
At this moment, it is plain text in memory.
2. PHP creates a bcrypt hash
$hash = password_hash($password, PASSWORD_BCRYPT);
PHP does several things internally:
- generates a random salt
- combines the password and salt
- runs the bcrypt algorithm
- returns a string containing the algorithm info, cost, salt, and resulting hash
The result may look like this:
$y$
Real World Use Cases
bcrypt is used anywhere an application needs to store user passwords securely.
Common examples
- User registration systems in websites and web apps
- Login systems for admin panels, dashboards, and APIs
- Password reset flows after a user chooses a new password
- Internal tools where staff accounts need secure authentication
- Membership platforms such as forums, LMS apps, and e-commerce sites
Example scenarios
A blog CMS
When an editor creates an account, the CMS stores a bcrypt-based password hash in the users table.
An API backend
An API authenticates users with email and password before issuing a token. The password is verified with password_verify().
A SaaS application
When security settings improve, the app can detect outdated hashes and rehash them using password_needs_rehash() after a successful login.
Real Codebase Usage
In real projects, developers usually wrap password handling in small, reusable flows rather than scattering the logic everywhere.
Common patterns
Validation before hashing
<?php
if (empty($_POST['password'])) {
throw new InvalidArgumentException('Password is required.');
}
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
This avoids hashing empty or invalid input.
Verify during login
<?php
if (!password_verify($password, $user['password_hash'])) {
return 'Invalid credentials';
}
This is a common guard-clause style: fail early if the password is wrong.
Rehash when needed
<?php
if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT)) {
= (, PASSWORD_DEFAULT);
}
Common Mistakes
1. Using MD5 or SHA-1 for passwords
These algorithms are too fast for password storage.
Bad
<?php
$hash = md5($password);
Better
<?php
$hash = password_hash($password, PASSWORD_DEFAULT);
2. Trying to decrypt password hashes
A password hash is not meant to be decrypted.
Wrong idea
<?php
// There is no correct way to decrypt a password hash
Correct approach
Use password_verify() to compare a plain password to a stored hash.
3. Manually creating salts unnecessarily
Older tutorials often show manual salt handling. With password_hash(), PHP handles salt generation for you.
Unnecessary
<?php
$salt = bin2hex(());
= (, );
Comparisons
| Concept | Purpose | Reversible? | Good for passwords? | PHP tool |
|---|---|---|---|---|
| bcrypt | Password hashing | No | Yes | password_hash() |
| Encryption | Protect readable data that must be recovered later | Yes | No | openssl_encrypt() |
| MD5 | Fast general hash | No | No | md5() |
| SHA-1 / SHA-256 alone | Fast general hash | No | Not recommended alone | hash() |
Cheat Sheet
Quick reference
Hash a password
$hash = password_hash($password, PASSWORD_DEFAULT);
Use bcrypt explicitly
$hash = password_hash($password, PASSWORD_BCRYPT);
Verify a password
if (password_verify($password, $storedHash)) {
// valid
}
Rehash if needed
if (password_needs_rehash($storedHash, PASSWORD_DEFAULT)) {
$newHash = password_hash($password, PASSWORD_DEFAULT);
}
Rules
- Store only the hash, not the plain password.
- Do not decrypt password hashes.
- Do not use MD5 or SHA-1 for password storage.
- Do not compare bcrypt hashes by re-hashing input manually.
- Let
password_hash()manage the salt.
FAQ
What is bcrypt in PHP?
bcrypt is a password hashing algorithm. In PHP, you typically use it through password_hash() and verify with password_verify().
Does PHP have a bcrypt function?
Not usually by that exact name. PHP exposes bcrypt through the password API, especially password_hash($password, PASSWORD_BCRYPT).
Can bcrypt hashes be decrypted?
No. bcrypt is a one-way password hashing algorithm, not reversible encryption.
Why not use MD5 for passwords in PHP?
MD5 is too fast and too weak for password storage. Attackers can test huge numbers of guesses very quickly.
Should I use PASSWORD_BCRYPT or PASSWORD_DEFAULT?
For most new applications, PASSWORD_DEFAULT is preferred because PHP can move to stronger defaults in future versions.
Do I need to store the salt separately?
No. The hash generated by password_hash() already contains the salt and other metadata.
How do I check whether an old hash should be upgraded?
Use password_needs_rehash() after a successful login and save a new hash if needed.
Mini Project
Description
Build a simple PHP password registration and login example that demonstrates the correct use of bcrypt-based hashing through PHP’s password API. This project shows how a password is hashed once during registration and verified later during login without ever storing the plain password.
Goal
Create a small script that hashes a password, stores the hash in a variable, and verifies login attempts correctly.
Requirements
Requirement 1 Requirement 2 Requirement 3
Keep learning
Related questions
Converting HTML and CSS to PDF in PHP: Core Concepts, Limits, and Practical Approaches
Learn how HTML-to-PDF conversion works in PHP, why CSS support varies, and how to choose practical approaches for reliable PDF output.
How PHP foreach Actually Works with Arrays
Learn how PHP foreach works internally, including array copies, internal pointers, by-value vs by-reference behavior, and common pitfalls.
How to Check String Prefixes and Suffixes in PHP
Learn how to check whether a string starts or ends with specific text in PHP using simple functions and practical examples.