Bạn từng nghe về việc dữ liệu bị đánh cắp chưa? Ồ, nó không chỉ là kịch bản phim Hollywood đâu nhé. Các công ty mất hàng triệu đô vì rò rỉ dữ liệu, còn danh tiếng thì sụp đổ như nhà làm bằng bài. Để không bị như vậy, dữ liệu nhất định phải được bảo vệ. Một trong những cách mạnh nhất — chính là mã hóa.
Mã hóa là cách biến dữ liệu thành "mã bí mật" mà không có key thì không ai hiểu nổi. Trong PostgreSQL có extension xịn tên là pgcrypto, giúp việc mã hóa dữ liệu của bạn dễ như ăn bánh.
pgcrypto — là extension của PostgreSQL, cung cấp công cụ mạnh để mã hóa, giải mã dữ liệu, làm việc với hash và tạo dữ liệu ngẫu nhiên.
Những gì pgcrypto làm được:
- Mã hóa đối xứng (một key) và bất đối xứng (cặp key: private và public).
- Hash dữ liệu để kiểm tra (ví dụ như mật khẩu).
- Tạo dữ liệu ngẫu nhiên, dùng để tạo token, key và mật khẩu.
Đây là cách bật pgcrypto trong database của bạn. Nếu bạn nghĩ chỉ có phù thủy Hogwarts mới dùng được phép thuật, thì PostgreSQL sẽ làm bạn bất ngờ đấy.
-- Kết nối extension pgcrypto
CREATE EXTENSION IF NOT EXISTS pgcrypto;
Mã hóa đối xứng: Mã hóa bí mật của bạn
Các function để mã hóa và giải mã:
pgp_sym_encrypt(data, key)— mã hóa dữ liệu bằng key đối xứng.pgp_sym_decrypt(data, key)— giải mã dữ liệu đã mã hóa bằng cùng key đó.
Ví dụ: mã hóa text đơn giản
Giả sử bạn có bảng users với cột email, và bạn muốn mã hóa địa chỉ email.
-- Tạo bảng users
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT
);
-- Thêm dữ liệu
INSERT INTO users (email)
VALUES ('user1@example.com'), ('user2@example.com');
-- Mã hóa dữ liệu
UPDATE users
SET email = pgp_sym_encrypt(email, 'supersecretkey');
-- Kiểm tra kết quả
SELECT * FROM users;
Kết quả: cột email giờ chứa text đã mã hóa, nhìn như một đống ký tự vô nghĩa.
Giải mã dữ liệu
Khi bạn muốn lấy lại dữ liệu gốc, dùng function pgp_sym_decrypt.
-- Giải mã dữ liệu
SELECT pgp_sym_decrypt(email::bytea, 'supersecretkey') AS original_email
FROM users;
Lưu ý: đừng tiết kiệm key. Key kiểu "123456" thì cũng như đặt mật khẩu cửa rồi để cửa mở toang. Hãy dùng key dài và khó đoán nhé.
Hash dữ liệu: bảo vệ mật khẩu kiểu "siêu cấp"
Lưu mật khẩu dạng plain text trong database cũng như giấu nhật ký dưới gối ở phòng tập thể. Đừng làm vậy! Thay vào đó hãy dùng hash.
Function để hash: crypt(password, gen_salt('bf')) — tạo hash cho chuỗi password bằng thuật toán Blowfish.
-- Ví dụ hash mật khẩu
SELECT crypt('my_password', gen_salt('bf'));
Kết quả sẽ kiểu như: $2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi.
Để kiểm tra mật khẩu, dùng lại function này:
-- Kiểm tra mật khẩu
SELECT crypt('my_password', '$2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi')
= '$2a$10$Efgnd3tFs3tOH6r3RgW5/uLPhNTa43k5E2C5Ut0Ydo7RNHZjG.vi';
Kết quả: true.
Lời khuyên: đừng bao giờ lưu mật khẩu dạng plain text. Dù bạn nghĩ database của mình an toàn cỡ nào, luôn luôn dùng hash nhé.
Mã hóa bất đối xứng: Hai key vẫn hơn một key
Mã hóa bất đối xứng dùng hai key:
- Public key (để mã hóa).
- Private key (để giải mã).
Ví dụ: mã hóa bằng public key
-- Tạo cặp key (cho đơn giản lưu vào biến)
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 $$;
Ứng dụng mã hóa bất đối xứng
Hệ thống hiện đại thường dùng mã hóa bất đối xứng để trao đổi dữ liệu, ví dụ như trong kết nối SSL.
Tạo dữ liệu ngẫu nhiên
Để tạo token hoặc key ngẫu nhiên, dùng function gen_random_uuid hoặc gen_random_bytes.
Ví dụ:
-- Tạo UUID ngẫu nhiên
SELECT gen_random_uuid();
-- Tạo mảng byte ngẫu nhiên
SELECT gen_random_bytes(16);
Cái này hữu ích để tạo id duy nhất, token truy cập hoặc mật khẩu ngẫu nhiên.
Kịch bản dùng pgcrypto
- Mã hóa dữ liệu nhạy cảm:
- Số thẻ tín dụng.
- Dữ liệu cá nhân khách hàng (ví dụ địa chỉ, số điện thoại).
- Hồ sơ y tế.
Hash mật khẩu: Đảm bảo ngay cả admin database cũng không xem được mật khẩu user.
Truyền dữ liệu an toàn: Dùng mã hóa bất đối xứng để truyền thông tin đã mã hóa.
Tạo token: Tạo token cho xác thực user API.
Lỗi thường gặp khi làm việc với mã hóa
Lưu key ở nơi ai cũng truy cập được. Đừng bao giờ lưu key mã hóa dạng plain text trong database. Hãy dùng secret manager nhé.
Dùng key yếu. Nếu key mã hóa quá ngắn, người ta có thể đoán ra được.
Mã hóa không cần thiết. Mã hóa làm tăng tài nguyên xử lý dữ liệu. Chỉ dùng khi thực sự cần thôi.
Quên mất đã dùng key nào. Thiếu tài liệu hệ thống có thể khiến bạn không giải mã được dữ liệu.
Mã hóa không khó, mà là bước hợp lý để bảo vệ dữ liệu của bạn. Hãy dùng pgcrypto trong project của bạn, và bạn sẽ biến database thành pháo đài bất khả xâm phạm, chuẩn như yêu cầu của thời đại. PostgreSQL cho bạn đủ công cụ để biến dữ liệu thành thành trì vững chắc.
GO TO FULL VERSION