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

PHP 常用加密函數詳解:MD5、Crypt、SHA1、Urlencode、Base64 實戰指南

     編輯:PHP 相關知識

PHP 常用加密函數詳解:MD5、Crypt、SHA1、Urlencode、Base64 實戰指南

加密與編碼是 Web 安全的基石。PHP 內置了多種函數,但它們的適用場景、安全性、可逆性差異巨大。本文系統梳理 5 大常用函數的原理、參數、代碼示例及最佳實踐,助你避開安全坑。

1. MD5 —— 最經典的單向散列(已不推薦用於密碼)

string md5 ( string $str [, bool $raw_output = false ] )
  • 輸出: 默認 32 字符十六進制;raw_output=true 時輸出 16 字節二進制。
  • 特性: 單向、定長、極快、無解密算法。
  • 安全現狀: 存在碰撞攻擊,彩虹表可破解常見弱密碼。**嚴禁直接用於密碼存儲。**
  • 加固建議: 多次散列 md5(md5($pwd).$salt)、或配合 hash_hmac('md5', $data, $key),但仍不如 bcrypt/Argon2。
<?php
$pwd = 'jellybool.com';
echo md5($pwd);               // 7bf02cf0f4af6da4accbc73d2a175476
echo md5(md5($pwd));          // 864704bb35754f8cd0232cba6b91521b 雙重增加破解難度
?>

2. Crypt —— 內置鹽值的單向散列(支援多算法)

string crypt ( string $str [, string $salt ] )
  • 鹽值: 若省略,PHP 自動生成;自定義鹽值決定算法(如 $1$ 開頭為 MD5、$2y$ 為 Blowfish/bcrypt)。
  • 推薦用法: crypt($pwd, '$2y$10$' . $salt) 使用 bcrypt,成本因子 10,抗 GPU 破解。
  • 注意: PHP 5.5+ 應優先使用 password_hash() / password_verify(),它們封裝了 bcrypt/Argon2 並自動處理鹽值。
<?php
$pwd = 'jellybool.com';
echo crypt($pwd);                    // $1$Fe0.qr5.$WOhkI4/5VPo7n7TnXHh5K (MD5-based)
echo crypt($pwd, 'je');              // je7fNiu1KNaEs (DES-based, 僅前 2 字符有效,極不安全)
echo crypt($pwd, '$1$jellybool$');   // $1$jellyboo$DxH7wF7SygRpWb6XBBgfH/ (MD5-based, 鹽值 8 字符)
?>

3. SHA1 —— 比 MD5 稍長的單向散列(同樣不推薦用於密碼)

string sha1 ( string $str [, bool $raw_output = false ] )
  • 輸出 40 字符十六進制(20 字節二進制)。
  • 同樣存在碰撞風險,不適用於密碼存儲。可用於文件完整性校驗、Git 提交 ID 等非安全場景。
  • 混合使用 md5(sha1($str)) 略微增加破解成本,但本質未變。

4. Urlencode —— URL 編碼(非加密,可逆,用於傳輸安全)

string urlencode ( string $str )
string urldecode ( string $str )
  • 作用: 將非字母數字字符(除 -_.)轉為 %XX 格式,空格變 +。確保 URL 參數不破壞結構。
  • 典型場景: 構建 GET 請求參數、表單提交、OAuth 回調 URL。
  • 常見轉換: ?=>%3F, ==>%3D, %=>%25, &=>%26, 空格=>+。
<?php
$url = 'jellybool.com?jellybool=true + 4-3%5= \& @!';
$encoded = urlencode($url);
// jellybool.com%3Fjellybool%3Dtrue+%2B+4-3%255%3D+%5C%26+%40%21
echo urldecode($encoded); // 完美還原

// 解決參數值包含 & 導致解析錯誤
$username = 'jelly&bool';
$safeUrl = "jellybool.com?username=" . urlencode($username) . "&password=jelly";
?>

5. Base64 —— 二進制到文本編碼(可逆,非加密)

string base64_encode ( string $data )
string base64_decode ( string $data )
  • 用途: 圖片/文件嵌入 HTML/CSS/JSON(Data URI)、Basic Auth 認證頭、傳輸二進制數據通道。輸出長度約為原長 4/3,字符集 A-Z a-z 0-9 + / =。
  • 注意: **不提供任何機密性**,僅是編碼。敏感數據必須先加密再 Base64。
  • 圖片轉 Base64 示例:
<?php
$imgUrl = 'https://example.com/logo.png';
$data = file_get_contents($imgUrl);
$base64 = base64_encode($data);
// 輸出: data:image/png;base64,$base64 可直接用于 
?>

安全選型總結表

需求推薦方案禁用/慎用
用戶密碼存儲password_hash($pwd, PASSWORD_BCRYPT/ARGON2ID) + password_verify()MD5, SHA1, Crypt(手動), 明文
API 簽名/防篡改hash_hmac('sha256', $data, $secret_key)單純 MD5/SHA1
URL 參數傳遞urlencode() / http_build_query()手動拼接
二進制嵌入文本base64_encode()無
文件完整性校驗hash_file('sha256', $file)MD5 (大文件碰撞風險)

現代最佳實踐:忘掉手動加密,用 PHP 內置密碼 API

<?php
// 註冊/修改密碼
$hash = password_hash($_POST['password'], PASSWORD_ARGON2ID); // PHP 7.2+
// 存入資料庫 $hash (包含算法、成本、鹽值)

// 登錄驗證
if (password_verify($_POST['password'], $dbHash)) {
    // 成功
    // 可選:檢查是否需要重新哈希 (算法升級、成本調整)
    if (password_needs_rehash($dbHash, PASSWORD_ARGON2ID)) {
        $newHash = password_hash($_POST['password'], PASSWORD_ARGON2ID);
        // 更新資料庫
    }
}
?>

這組 API 自動處理鹽值生成、算法標識、驗證、升級,是 PHP 5.5+ 版本處理密碼的**唯一正確方式**。

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