One-way password crypting flaws

MD5 with a two-hex-digit salt is not password storage. Use a modern KDF with per-user salt and iteration.

Password storage is not a CRC, not a truncated hash, and not a single MD5 pass.

Minimum bar

  • Use a password KDF / digital fingerprint designed for secrets — not CRC, not a general checksum
  • Store the full digest
  • Per-user salt of real entropy (not two hex characters)
  • Iterate (stretch) so offline attacks pay CPU
  • Prefer modern constructs (bcrypt / scrypt / Argon2 / vetted wrappers such as phpass) over home-rolled MD5/SHA1

A common PHP pattern (flawed)

Several ecommerce trees derived from old osCommerce-style code stored md5(salt || password) : salt with:

$salt = substr(md5($password), 0, 2); // hex → 256 possibilities
$password = md5($salt . $plain) . ':' . $salt;

Problems: 2-character hex salt (256 values), weak PRNG seeding, no iteration, MD5 as the primitive. Precomputing 256 dictionaries is cheap. Equal plaintexts collide often across users.

Migration without downtime

Lengthen salt, switch KDF, widen the column. Detect legacy rows by encoded length/format; on successful login, re-hash with the new scheme. Follow OWASP Password Storage when building new code.