PHP - 散列:初學者指南

Hello, 有志於PHP開發的各位!今天,我們將踏上一段令人興奮的旅程,進入散列(Hashing)的世界。如果你之前從未聽說過散列,也不用擔心 - 在這個教學結束之前,你將會像專家一樣進行散列!

PHP - Hashing

什麼是散列?

在我們深入細節之前,讓我們先從基礎開始。想像你有一個秘密訊息,並且你想把它轉換成一個無法解密的代碼。這就是散列的基本作用!它將你的輸入(如密碼或文件)轉換成固定大小的字符串。這個字符串叫做散列值。

這裡有一個有趣的比喻:把散列想像成一個神奇的攪拌機。你放入任何食材(你的輸入),它總是會給你一杯大小相同的冰沙(散列值),但會根據你放入的食材有不同的口味。

散列的應用

現在,你可能會想,“我們為什麼需要散列?”問得好!在計算機世界中,散列有許多應用。讓我們探討一些:

  1. 密碼存儲:網站會存儲你的密碼的散列值,而不是明文(這在安全性上是絕對禁止的)。當你登錄時,他們會對你輸入的內容進行散列,並與存儲的散列值進行比較。

  2. 數據完整性:散列可以驗證文件是否被篡改。即使只有一個字節的變化,整個散列值也會不同!

  3. 數字簽名:這些使用散列來確保數字文件的真實性。

  4. 緩存:大型網站使用散列來快速檢索緩存數據。

散列的過程

讓我們將散列過程分解為簡單的步驟:

  1. 對一個輸入(如密碼)進行散列。
  2. 將散列算法應用於它。
  3. 獲得一個固定大小的輸出(散列值)。

這裡有趣的部分是:無論你的輸入多長或多短,對於給定的算法,輸出(散列值)總是會有相同的長度。

PHP中的散列算法

PHP支持多種散列算法。讓我們看看一些最常見的:

  1. MD5(消息摘要算法5)
  2. SHA-1(安全散列算法1)
  3. SHA-256(SHA-2家族的一部分)
  4. Bcrypt(對於密碼特別適用)

這些每個都有其優勢和應用案例。例如,bcrypt專門為密碼散列設計,並且比MD5或SHA-1更安全。

PHP中的散列函數

現在,讓我們親自動手寫一些PHP代碼!PHP提供了多個內置的散列函數。這裡是一個常用函數的表格:

函數 描述
md5() 計算字符串的MD5散列
sha1() 計算字符串的SHA-1散列
hash() 使用各種算法生成散列值
password_hash() 創建密碼散列(推薦用於密碼)
crc32() 計算字符串的CRC32多項式

讓我們看看如何使用這些函數的一些例子:

1. MD5散列

$string = "Hello, World!";
$md5_hash = md5($string);
echo "MD5散列值 of '$string': " . $md5_hash;

輸出:

MD5散列值 of 'Hello, World!': 65a8e27d8879283831b664bd8b7f0ad4

在這個例子中,我們使用md5()函數來散列字符串"Hello, World!"。生成的散列值總是32個字符長,無論輸入的長度如何。

2. SHA-1散列

$string = "PHP is awesome!";
$sha1_hash = sha1($string);
echo "SHA-1散列值 of '$string': " . $sha1_hash;

輸出:

SHA-1散列值 of 'PHP is awesome!': 4eb40c4bde4d39f32ab9064ec9c93396f6fdcf9f

sha1()函數的工作原理與md5()相似,但它生成的是40個字符的散列值。

3. 使用hash()函數

hash()函數更為通用,允許你指定使用哪種算法:

$string = "Hashing is fun!";
$algorithms = ['md5', 'sha1', 'sha256'];

foreach ($algorithms as $algo) {
$hash = hash($algo, $string);
echo "Hash of '$string' using $algo: " . $hash . "\n";
}

輸出:

Hash of 'Hashing is fun!' using md5: 4d6b94ef062847891a1e97a716541059
Hash of 'Hashing is fun!' using sha1: 8a7ced2e4a8d64daa28566150c2add1c04812e53
Hash of 'Hashing is fun!' using sha256: 7b1b6d4c6e48183f2b1b3f2847736fb93339f45e254cb21330f3d0adc3e6d3db

這個例子展示了不同的算法對同一輸入生成不同長度和值的散列。

4. 密碼散列

對於密碼散列,推薦使用password_hash()函數:

$password = "mySecurePassword123";
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
echo "Hashed password: " . $hashed_password;

輸出:

Hashed password: $2y$10$6Q5DYfJKCsa7C/eV4Wh9OeDjTJ0XLB.Vr7F1C5E6kJRBVWPwMDKP.

這個函數自動使用一個強大的散列算法(當前是bcrypt)並添加鹽以增加安全性。

為了驗證密碼與其散列值,使用password_verify()

$password = "mySecurePassword123";
$hashed_password = password_hash($password, PASSWORD_DEFAULT);

if (password_verify($password, $hashed_password)) {
echo "Password is correct!";
} else {
echo "Password is incorrect.";
}

輸出:

Password is correct!

這種方法比直接比較散列更安全,因為它設計成對時間攻擊具有抵抗性。

結論

恭喜你!你剛剛在PHP的散列世界中邁出了第一步。記住,散列是單向過程 - 你無法從散列值“反散列”來獲得原始輸入。這正是它在安全領域如此有用的原因。

隨著你繼續在PHP的道路上前進,你會發現散列有更多用途。它是計算機科學和網絡安全的基本概念,理解它將會在你的編程生涯中大有幫助。

持續練習,保持好奇心,並且快樂散列!

Credits: Image by storyset