你有聽過資料被偷嗎?欸這可不是只有好萊塢電影才會發生的事。公司因為資料外洩損失好幾百萬美金,名聲也像紙牌屋一樣垮掉。為了不讓這種事發生,資料一定要保護好。最強的做法之一就是加密啦。
加密就是把資料變成「祕密代碼」的方法,沒有解密 key 根本看不懂。PostgreSQL 有個超好用的擴充套件叫 pgcrypto,可以讓你很輕鬆地加密你的資料。
pgcrypto 是 PostgreSQL 的一個 extension,提供強大的加密、解密、雜湊還有產生隨機資料的工具。
pgcrypto 的主要功能:
- 支援對稱式加密(一把 key)跟非對稱式加密(一對 key:private 跟 public)。
- 資料雜湊,像是驗證密碼用的。
- 產生隨機資料,可以拿來做 token、key、密碼什麼的。
來看看怎麼在你的資料庫裡裝好 pgcrypto。如果你以前覺得魔法只有霍格華茲的巫師才會用,PostgreSQL 會讓你大開眼界。
-- 安裝 pgcrypto 擴充套件
CREATE EXTENSION IF NOT EXISTS pgcrypto;
對稱式加密:把你的祕密藏起來
加密跟解密的函式:
pgp_sym_encrypt(data, key)— 用對稱 key 加密資料。pgp_sym_decrypt(data, key)— 用同一把 key 解密資料。
範例:加密純文字
假設我們有個 users 資料表,裡面有 email 欄位,我們想把 email 加密起來。
-- 建立 users 資料表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT
);
-- 插入資料
INSERT INTO users (email)
VALUES ('user1@example.com'), ('user2@example.com');
-- 加密資料
UPDATE users
SET email = pgp_sym_encrypt(email, 'supersecretkey');
-- 檢查結果
SELECT * FROM users;
結果:email 欄位現在存的是加密後的亂碼,看起來完全沒意義。
資料解密
如果你要把資料還原,用 pgp_sym_decrypt 這個函式就對了。
-- 解密資料
SELECT pgp_sym_decrypt(email::bytea, 'supersecretkey') AS original_email
FROM users;
小提醒:key 千萬不要亂設。像 "123456" 這種 key 就跟你家門口貼密碼一樣,還直接開門給人進。key 要長又複雜才安全。
資料雜湊:密碼保護超進化
把密碼明碼存資料庫就跟把日記藏在合租公寓的枕頭下一樣,千萬別這樣!要用雜湊才安全。
雜湊函式: crypt(password, gen_salt('bf')) — 用 Blowfish 演算法幫 password 產生雜湊。
-- 密碼雜湊範例
SELECT crypt('my_password', gen_salt('bf'));
結果大概會長這樣:$2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi。
要驗證密碼也很簡單,用同一個函式:
-- 密碼驗證
SELECT crypt('my_password', '$2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi')
= '$2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi';
結果:true。
小建議:密碼絕對不要明碼存。就算你覺得資料庫超安全,也一定要用雜湊。
非對稱式加密:兩把 key 比一把還強
非對稱式加密會用到兩把 key:
- Public key(加密用)。
- Private key(解密用)。
範例:用 public key 加密
-- 產生一對 key(這裡直接存在變數裡)
DO $$
DECLARE
public_key TEXT;
private_key TEXT;
BEGIN
SELECT pgp_keygen_keys(1024, 'my_passphrase')
INTO public_key, private_key;
RAISE NOTICE 'Public Key: %', public_key;
RAISE NOTICE 'Private Key: %', private_key;
END $$;
非對稱式加密的應用
現在很多系統都用非對稱式加密來傳資料,像 SSL 連線就是這樣搞的。
產生隨機資料
要做 token 或隨機 key,可以用 gen_random_uuid 或 gen_random_bytes。
範例:
-- 產生隨機 UUID
SELECT gen_random_uuid();
-- 產生隨機 byte 陣列
SELECT gen_random_bytes(16);
這很適合拿來做唯一識別碼、存取 token 或隨機密碼。
pgcrypto 的應用場景
- 加密敏感資料:
- 信用卡號。
- 客戶個資(像地址、電話)。
- 醫療紀錄。
密碼雜湊: 就算是資料庫管理員也看不到用戶密碼。
安全傳輸資料: 用非對稱式加密來傳加密資訊。
產生 token: 做 API 使用者驗證的 token。
加密常見的地雷
把 key 放在大家都找得到的地方。 千萬不要把加密 key 明碼存在資料庫。要用 secrets manager 來存。
用太弱的 key。 key 太短很容易被猜到。
沒必要也加密。 加密會讓資料處理變慢,真的需要才用。
忘記用哪個 key 了。 沒有寫好文件,最後資料解不開就 GG 了。
加密其實不難,重點是要有邏輯地保護你的資料。把 pgcrypto 用進你的專案,資料庫就會變超安全,也更符合現代的安全標準。PostgreSQL 給你所有把資料變成銅牆鐵壁的工具。
GO TO FULL VERSION