The way I've tried to get around it is instead of storing a hash of the password, storing the a1 hash in the database (i.e. md5($username.":".$realm.":".$password); ). I've got this working OK for authentication through a form, but not through HTTP. Here's the class I've written:
Code: Select all
class auth_digest {
public $username;
public $nonce;
public $uri;
public $response;
public $qop;
public $nc;
public $cnonce;
public function __construct($digest) {
if(preg_match('/username="([^"]+)"/', $digest, $username)
&& preg_match('/nonce="([^"]+)"/', $digest, $nonce)
&& preg_match('/uri="([^"]+)"/', $digest, $uri)
&& preg_match('/response="([^"]+)"/', $digest, $response)
&& preg_match('/qop="?([^,\s"]+)/', $digest, $qop)
&& preg_match('/nc=([^,\s"]+)/', $digest, $nc)
&& preg_match('/cnonce="([^"]+)"/', $digest, $cnonce)) {
$this->username = $username[1];
$this->nonce = $nonce[1];
$this->uri = $uri[1];
$this->response = $response[1];
$this->qop = $qop[1];
$this->nc = $nc[1];
$this->cnonce = $nonce[1];
return true;
} else {
return false;
}
}
public function authenticate($hash) {
$A1 = $hash;
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$this->uri);
$valid_response = md5($A1.':'.$this->nonce.':'.$this->nc.':'.$this->cnonce.':'.$this->qop.':'.$A2);
if ($valid_response == $this->response) {
return true;
} else {
return false;
}
}
};