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, scryptargon2

總結

  1. crypto.createHash 是最簡單的單向指紋工具。
  2. 需要驗證身分或 API 簽名時,請選用 crypto.createHmac
  3. 處理檔案校驗時,請搭配 Stream 以優化伺服器性能。