首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現 HTTP Digest 摘要式身份驗證完整範例

     編輯:PHP 綜合知識

Digest 認證流程

  1. 伺服器回應 401 Unauthorized,附帶 WWW-Authenticate: Digest realm="...", nonce="...", algorithm=MD5, qop="auth"。
  2. 瀏覽器彈出登入框,使用者輸入帳密。
  3. 瀏覽器計算 response = MD5(A1:nonce:nc:cnonce:qop:A2) 並送回 Authorization 標頭。
  4. 伺服器同樣計算 response 比對,一致則驗證通過。

關鍵公式

A1 = MD5(username:realm:password)
A2 = MD5(method:uri)
response = MD5(A1:nonce:nc:cnonce:qop:A2)

完整 PHP 實作

<?php
$realm = 'MyRealm';

if (!isset($_SERVER['PHP_AUTH_DIGEST'])) {
    header('WWW-Authenticate: Digest realm="'.$realm.'",nonce="'.uniqid().'",algorithm=MD5,qop="auth"');
    header('HTTP/1.0 401 Unauthorized');
    exit('認證失敗');
}

$data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']);
if (!$data) {
    header('HTTP/1.0 401 Unauthorized');
    exit('解析失敗');
}

// 從資料庫查詢真實密碼,此處示範寫死
$A1 = md5('admin:'.$realm.':password');
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

if ($data['response'] === $valid) {
    echo '驗證通過!';
} else {
    header('HTTP/1.0 401 Unauthorized');
    exit('帳號/密碼錯誤');
}

function http_digest_parse($txt) {
    $need = ['nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1];
    preg_match_all('@(\w+)=(["\']?)([^"\']+)\2@', $txt, $m, PREG_SET_ORDER);
    $data = [];
    foreach ($m as $v) {
        $data[$v[1]] = $v[3];
        unset($need[$v[1]]);
    }
    return $need ? false : $data;
}
?>

安全性補充

  • nonce 應包含時間戳,並驗證有效期(如 15 分鐘),防重放攻擊。
  • nc (nonce-count) 需檢查遞增,防重複使用。
  • 生產環境建議改用 algorithm=SHA-256 或 SHA-512-256(RFC 7616),PHP 需自行實作對應雜湊。
  • HTTPS 環境下才建議使用 Digest,否則帳密雖未明文傳輸,但可被中間人降級攻擊。

結語

Digest 認證雖比 Basic 安全,但實作複雜且仍有已知弱點。現代 Web 應優先採用 OAuth 2.0 / JWT / Session-Cookie 等成熟方案,Digest 適用於無法部署 HTTPS 的舊式內網設備或 API 相容場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved