This article is for developers who want to understand and correctly apply hash functions in PHP. We compare MD5 and SHA-1, offering clear and practical advice on their principles, output, collision resistance, speed, typical use cases, and real-world usage in PHP, while also introducing safer alternatives and usage considerations.
Hash function: Accepts input of arbitrary length and produces a fixed-length “digest.” Commonly used for data integrity verification, as the basis for digital signatures, indexing, etc.
Irreversibility: A hash function should be one-way — in theory, it should not be possible to reconstruct the original input from the digest (though this depends on the attacker’s capability).
Collision: When two different inputs produce the same output. An ideal hash should make finding collisions extremely difficult.
Output Length
MD5: 128 bits, usually represented as a 32-character hex string (e.g., d41d8cd98f00b204e9800998ecf8427e).
SHA-1: 160 bits, usually represented as a 40-character hex string (e.g., da39a3ee5e6b4b0d3255bfef95601890afd80709).
Security
MD5: Proven practical collision attacks exist. Should not be used in security-sensitive contexts (signatures, certificates, password storage, etc.).
SHA-1: Stronger than MD5 but also broken in practice (collisions demonstrated in research/experiments). It has been deprecated as a secure hash.
Speed
MD5 is typically faster than SHA-1 (due to shorter internal state and fewer operations), but on modern hardware speed differences are irrelevant — security matters more.
<?php
$data = "hello world";
<p>// MD5<br>
$md5 = md5($data); // 32 hex<br>
$md5_raw = md5($data, true); // raw binary 16 bytes</p>
<p>// SHA-1<br>
$sha1 = sha1($data); // 40 hex<br>
$sha1_raw = sha1($data, true); // raw binary 20 bytes</p>
<p>echo "MD5: $md5\n";<br>
echo "SHA1: $sha1\n";<br>
For message authentication with a key (more secure integrity checks), use HMAC:
<?php
$key = "secret-key";
$data = "important payload";
<p>// Recommended: stronger hash (e.g., sha256)<br>
$hmac = hash_hmac('sha256', $data, $key);<br>
echo "HMAC-SHA256: $hmac\n";<br>
Non-security unique identifiers / quick checks (low risk acceptable)
MD5 or SHA-1 can be used for file name hashing, simple cache keys, or quick deduplication checks (but not as a guarantee of strict consistency).
Security-sensitive scenarios (absolutely not recommended)
Password storage, digital signatures, TLS/certificate fingerprints, signature verification, etc.: Do not use MD5/SHA-1. Both are vulnerable to practical collision attacks (especially MD5), allowing attackers to forge different messages with the same digest.
File integrity checks
If the only concern is accidental corruption during transfer (not active adversaries), MD5/SHA-1 are still used on download pages. But if tampering is a concern, use stronger hashes (SHA-256/512) or signatures (HMAC/public key signatures).
MD5: Since the early 2000s, multiple practical collision and exploit attacks have been published. Widely abandoned for security purposes.
SHA-1: Long considered stronger than MD5, but research and experiments have shown real collisions (e.g., the 2017 academic demonstration). Should also be avoided in high-security contexts.
(Note: This is a brief overview. Public research and practical demonstrations show both are insufficient against collision attacks.)
Always use dedicated password hashing functions: Use password_hash() / password_verify(). PHP’s default (PASSWORD_DEFAULT) applies modern secure algorithms (like bcrypt or better) and automatically handles salting and cost factors.
<?php
// Password hashing and verification (example)
$password = 'user-password';
$hash = password_hash($password, PASSWORD_DEFAULT);
// Store $hash in the database
if (password_verify($password, $hash)) {
// Verified
}
Use HMAC or signatures for message integrity and authentication: In adversarial environments, use hash_hmac() (e.g., with sha256 or sha512), or public key signatures (openssl_sign, etc.):
<?php
$tag = hash_hmac('sha256', $message, $secret_key);
For general hashing, prefer SHA-2 or SHA-3 families: For example, sha256, sha512. In PHP, use hash('sha256', $data) or hash('sha512', $data). These are significantly stronger than MD5/SHA-1.
If binary efficiency is needed, use raw binary output (md5($data, true) / sha1($data, true)) and base64-encode the result for storage or transmission.
Don’t roll your own password hashing scheme with “salt + multiple hashing”: It’s error-prone and hard to maintain. Use the officially recommended password hashing APIs.
Output length: MD5 = 128 bits (32 hex), SHA-1 = 160 bits (40 hex).
Security: SHA-1 > MD5, but both are unsuitable for security-critical scenarios.
Speed: MD5 is slightly faster, but this should not influence choice (security first).
Recommended use: Only for non-security identifiers or compatibility cases. For security, use SHA-2/SHA-3/HMAC/password_hash.
If you’re writing new code and care about security, do not use MD5 or SHA-1 — use hash('sha256', $data) / hash_hmac('sha256', $data, $key) for integrity and authentication, and password_hash() for passwords. Only consider MD5/SHA-1 for legacy compatibility or non-security scenarios.