📖 PHP Password Encryption

Passwords are one of the most common ways to authenticate users and control access to websites. Even though other technologies (like biometrics or token-based login) are gaining traction, passwords remain essential for small- to mid-size applications — including ours.

However, storing user passwords in plain text is no longer acceptable. If your site database is ever exposed, unhashed passwords can be stolen and reused on other systems. That's why modern PHP applications use built-in functions to encrypt passwords before saving them to the database.

Our goal in this article is to help you implement secure password handling in your custom MVC app using PHP’s password_hash() and password_verify() functions. We'll also introduce strategies to improve password strength and ensure encrypted connections using HTTPS.

By the end of this guide, you'll understand how to:

  • Use encrypted HTTPS connections for form submission
  • Hash and verify passwords using PHP’s built-in tools
  • Validate strong passwords using HTML, PHP, and JavaScript

Secured Connections

Every time you visit a website, your browser sends a request to a remote server, and that server responds by delivering the requested page. In the early days of the internet, most of these pages were static and carried little risk. But as the web evolved, traffic began crossing international networks — and carrying sensitive data like passwords, personal details, and payment information.

This global traffic can be intercepted unless it's encrypted. That's why modern websites use secure communication protocols to protect data in transit. This is where HTTPS comes in — the secure version of HTTP.

When a site uses HTTPS, it has a valid SSL/TLS certificate. This allows the browser and server to exchange data securely using encryption keys. You can recognize HTTPS in your browser’s address bar — it usually appears with a lock icon.

Using HTTPS helps protect your users while they fill out forms or log in. But keep in mind: HTTPS only secures data in transit. Once the data reaches your server, it still needs protection in storage — and that’s where password encryption becomes critical.

Password Encryption

Once user data reaches your server, it’s your responsibility to protect it — especially passwords. That’s where encryption comes in. In modern PHP development, we don’t store raw passwords. Instead, we use a process called hashing to convert a plain-text password (like fluffythecat2401) into a scrambled string that can’t be reversed or read.

This hashed version of the password — also known as a digest — is what we store in the database. When the user logs in, PHP hashes the entered password again and compares it to the stored hash. If they match, access is granted.

password_hash()
A built-in PHP function that automatically salts and hashes a password using the current best-practice algorithm (usually Bcrypt or Argon2). It ensures future compatibility by tagging the result with metadata.
password_verify()
This function takes a plain-text password and compares it to the stored hash, returning true if they match.
Hash
A one-way, fixed-length string generated from input data (like a password). Hashes cannot be reversed — that’s what makes them secure.

⚠️ Important: Older hash algorithms like MD5 and SHA1 are no longer considered secure and should never be used for password storage. Always use password_hash() to protect user credentials.

Modifying the Database

To store encrypted passwords, your database needs to allow enough space for the resulting hash string. PHP recommends using a VARCHAR(255) column to support all current and future hashing algorithms.

If your existing password column is shorter (such as VARCHAR(32)), you’ll need to update it. You can do this using phpMyAdmin’s table editor — or by running the following SQL command directly:

ALTER TABLE `users` MODIFY `password` VARCHAR(255);

This ensures your database is ready to store secure, future-proof password hashes created with password_hash().

Encrypting Passwords

Below is an example of how to encrypt passwords using password_hash(), a stronger hashing function compatible with crypt(). You can find a full explanation in the PHP documentation. This function is designed to support future improvements in encryption and can produce variable-length output. The example below demonstrates updating an existing password. When saving a new password during registration, the process is nearly the same — but uses an INSERT query instead of UPDATE.

Password Hashing Example (MVC Structure)

UserController.php
function update_user_password($userId, $newPassword) {
    $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
    return update_password_by_id($userId, $hashedPassword);
}
UserModel.php
function update_password_by_id($id, $hashedPassword) {
    global $pdo;

    $stmt = $pdo->prepare("UPDATE users SET password = :password WHERE id = :id");
    return $stmt->execute([
        ':password' => $hashedPassword,
        ':id' => $id
    ]);
}

💡 Tip: This separation keeps password logic reusable and testable. The controller handles the input; the model handles the SQL.

Password Authentication

Your login system already includes a login_user() function in the UserController. To support encrypted passwords, all you need to do is update the password comparison logic.

Previously, the password check looked like this:

if ($user && $password === $user['password'])

This only works if passwords are stored in plain text — which is not secure. Now that we're using password_hash() to encrypt user passwords, we need to use password_verify() instead. This function securely checks whether the submitted password matches the stored encrypted version:

if ($user && password_verify($password, $user['password']))

💡 Tip: To upgrade your login system for encrypted passwords, just replace the old plain-text comparison line with password_verify(). Everything else in your login logic remains unchanged.

Password Strength

One of the biggest vulnerabilities in database-driven websites is the user. Many users choose weak, easy-to-guess passwords — some even use “password” as their password. Your job as a developer is to build in safeguards to help them make better choices.

Modern browsers, JavaScript, and PHP can all help enforce password quality. This “layered” approach protects users at every step — from the form, through submission, and into the database.

Strong Password Pattern Matching

Let’s say we want to require passwords that:

  • Include at least one lowercase letter
  • Include at least one uppercase letter
  • Include at least one number
  • Are at least 8 characters long

You can use regular expressions (regex) to enforce these rules in both your HTML form and your PHP validation logic.

PHP Validation (Server Layer)

Even if the browser enforces rules, never trust client-side validation alone. Always re-check password strength on the server before saving:

if (!preg_match('/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/', $password)) {
    $password_error = "Must contain at least one number, one uppercase and lowercase letter, and at least 8 or more characters.";
    $valid = false;
}

⚠️ Important: Always validate passwords on the server. Browsers can be bypassed.

HTML Form Validation (Browser Layer)

The pattern attribute helps guide users before the form is submitted. Here’s how to add it to your password field:

<input
  type="password"
  id="password"
  name="password"
  value=""
  pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
  title="Must contain at least one number, one uppercase and lowercase letter, and at least 8 characters"
  required
/>

Try It In the Browser

Example Browser Password Validation

Using JavaScript for Validating and Matching Passwords

JavaScript is great for checking password strength in real time and ensuring users enter matching values. Since password fields are masked, it’s common to ask users to type it twice and confirm they match before submitting.

Here’s a working CodePen that shows how to check both strength and match using JavaScript:

CodePen Example

💡 Tip: Enforcing password rules at the browser, in JavaScript, and on the server ensures users get fast feedback — and you get strong, secure credentials in your database.

Last updated: August 1, 2025 at 7:16 PM