Node.js Crypto:雜湊 Hash 與資料完整性校驗
Node.js 內建的 crypto 模組是處理安全通訊、內容校驗與機密儲存的核心工具。本章我們將探討最基礎也最常用的安全技術:雜湊 (Hashing)。
什麼是雜湊 (Hashing)?
雜湊是一種「單向」且「不可逆」的數學運算。它可以將任意長度的資料(字串或二進位)輸入,並輸出為一個固定長度的「數位指紋」。
- 單向性:你無法從雜湊結果推算出原始輸入內容。
- 碰撞抵抗性:不同的內容幾乎不可能產出相同的雜湊值。
- 雪崩效應:輸入內容只要變動一個位元組,輸出的雜湊值就會發生翻天覆地的變化。
實戰:產生資料雜湊值
我們最常使用 SHA-256 作為目前的通用的工業標準。
const crypto = require('crypto');
const data = 'VerySecretMessage123';
// 建立 SHA-256 雜湊物件 -> 輸入數據 -> 產出十六進位字串
const hash = crypto.createHash('sha256').update(data).digest('hex');
console.log('SHA-256 雜湊指紋:', hash);
進階安全:HMAC (帶密鑰的雜湊)
如果你除了想確認資料沒被修改,還想確認資料是由「特定的人」發出的,則需要使用 HMAC (Hash-based Message Authentication Code)。它會合併一個「金鑰 (Secret Key)」來計算雜湊,這常用於 API 簽署。
const secret = 'my-app-secret-key';
const message = 'Hello World';
const hmac = crypto.createHmac('sha256', secret).update(message).digest('hex');
console.log('HMAC 簽章結果:', hmac);
檔案完整性校驗 (Checksum)
當你處理上傳檔案或下載大檔案時,為了省記憶體,應該使用 Stream (串流) 模式來逐步計算雜湊,而不是一次性將檔案塞進記憶體。
const fs = require('fs');
const hash = crypto.createHash('sha256');
const input = fs.createReadStream('update-package.zip');
input.on('data', (chunk) => {
hash.update(chunk); // 逐步處理數據塊
});
input.on('end', () => {
console.log('檔案校驗碼 (SHA-256):', hash.digest('hex'));
});
常見演算法比較表
| 演算法 | 安全性 | 建議用途 | 備註 |
|---|---|---|---|
| MD5 | ❌ 極低 | 僅限非安全性檔案校驗 | 易受碰撞攻擊,嚴禁存密碼 |
| SHA-1 | ❌ 低 | 舊式系統相容 | 已經不建議使用 |
| SHA-256 | ✅ 高 | 目前的工業標準 | 效能與安全性的最佳平衡 |
| SHA-512 | ✅ 極高 | 極高敏感度的資料校驗 | 運算開銷較大 |
密碼儲存禁忌:永遠不要直接使用 SHA-256 儲存使用者密碼!即使是 SHA-256,也容易遭受彩虹表 (Rainbow Table) 攻擊。儲存密碼應使用專門的演算法如 bcrypt, scrypt 或 argon2。
總結
crypto.createHash是最簡單的單向指紋工具。- 需要驗證身分或 API 簽名時,請選用
crypto.createHmac。 - 處理檔案校驗時,請搭配 Stream 以優化伺服器性能。