laszlo.nu

PHP implementation of the MySQL old_password function

MySQL has a built in function called password that calculates the hash of a password for secure storage in a database. In MySQL versions older than 4.1 the hashing function was very basic so all newer versions uses the cryptograpichally secure SHA-1 hashing algorithm (twice?).

It comes as no surprise that many older databases are full of hashes calculated using the older algorithm. Fortunately it is still available under the name old_password. I needed the hashes from the old_password function but I didn’t want to connect to a database server each time. I looked up the old_password (it’s actually called my_make_scrambled_password_323 internally) from the MySQL source code. It’s written in C so a rewrite in PHP was pretty trivial. PHP doesn’t have the unsigned integer concept so I had to do some adding in the end to make the results come out right. It hasn’t been tested much and it probably only works for plain ASCII so use it at your own risk. Here it goes.

function old_password($password) {
  if ($password == '')
    return '';
  $nr = 1345345333;
  $add = 7;
  $nr2 = 0x12345671;
  foreach(str_split($password) as $c) {
    if ($c == ' ' or $c == "\t")
      continue;
    $tmp = ord($c);
    $nr ^= ((($nr & 63) + $add) * $tmp) + ($nr << 8);
    $nr2 += ($nr2 << 8) ^ $nr;
    $add += $tmp;
  }

  if ($nr2 > PHP_INT_MAX)
    $nr2 += PHP_INT_MAX + 1;

  return sprintf("%x%x", $nr, $nr2);
}
  1. instabil posted this