Hash and Salt for Passwords in PHP: Best Practices 2025

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Hash, Salt, and Your Security: Why It Matters in 2025?

\n\n

Imagine: you've built a cool website, everything works, users are registering. But one day the database leaks online. What will attackers see? If you store passwords in plain text — it's a disaster. If you use old md5 — it's almost the same. But if you applied secure hash and salt — attackers will only see a meaningless set of characters. In 2025, this is not just a recommendation, but a security standard.

\n\n

In this article, we'll break down how to properly hash passwords in PHP using modern algorithms, salt, and best practices. You'll learn why old methods are dangerous and how to switch to secure password storage in 10 minutes.

\n\n

Why md5 and sha1 are Evil?

\n\n

Many beginner developers make the same mistake: using md5($password) or sha1($password). In 2025, this is not just bad practice, but a direct path to vulnerability. Why?

\n\n
    \n
  • Computation speed. MD5 and SHA1 were designed for speed, not security. Modern GPUs can brute-force billions of hashes per second.
  • \n
  • Lack of salt. If two users choose the same password, their hashes will be identical. This allows the use of rainbow tables.
  • \n
  • Collisions. Practical collisions have been found for MD5 — two different inputs produce the same hash.
  • \n
\n\n

Fortunately, PHP has built-in functions that solve all these problems. And this doesn't require installing third-party libraries.

\n\n

password_hash and password_verify: Your Secret Weapon

\n\n

Starting from PHP 5.5.0, two magical functions appeared in the language: password_hash() and password_verify(). They automatically generate a salt, use cryptographically strong algorithms, and protect against timing attacks.

\n\n

Example of simplest usage:

\n\n
// Hashing a password\n$password = "MySuperSecureP@ssw0rd!";\n$hash = password_hash($password, PASSWORD_DEFAULT);\necho $hash; // $2y$10$...\n
\n\n

What happened here? The password_hash function:

\n
    \n
  • Generated a random salt
  • \n
  • Selected the optimal algorithm (bcrypt by default)
  • \n
  • Computed the hash
  • \n
  • Returned a string that contains the hash, salt, and algorithm information
  • \n
\n\n

Verifying a password looks just as simple:

\n\n
// Verifying a password\n$inputPassword = "MySuperSecureP@ssw0rd!";\nif (password_verify($inputPassword, $hash)) {\n    echo "Password is correct!";\n} else {\n    echo "Password is incorrect.";\n}\n
\n\n

Note: you don't need to store the salt separately. It is already embedded in the hash. This is secure hash and salt in action.

\n\n

Which Algorithm to Choose in 2025?

\n\n

By default, password_hash uses bcrypt. This is an excellent choice for most projects. But we have other options:

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
AlgorithmConstantRecommendation
BcryptPASSWORD_BCRYPTExcellent choice, supported everywhere
Argon2iPASSWORD_ARGON2IResistant to side-channel attacks
Argon2idPASSWORD_ARGON2IDBest choice in 2025
\n\n

Argon2id is the winner of the PHC (Password Hashing Competition). It is resistant to both GPU attacks and timing attacks. If your PHP is compiled with Argon2 support (and in PHP 8.x it's already standard), use it.

\n\n

Configuring Hashing Cost

\n\n

One of the key ideas of secure hash and salt is to make the comp

Blogs

Book Recommendations