Quản trị dữ liệu 5 — Mã hóa, Masking & Tokenization
Quản trị dữ liệu 5 — Mã hóa, Masking & Tokenization
Bài trước đã trả lời câu hỏi dữ liệu này nhạy cảm đến mức nào: ta đã gán nhãn cho từng cột, biết đâu là CCCD, đâu là số thẻ, đâu là số dư. Bây giờ đến phần hành động: làm cách nào để cột đã gắn nhãn Restricted thật sự không đọc được bởi kẻ không có quyền? Câu trả lời không phải một kỹ thuật duy nhất mà là ba lớp bổ sung cho nhau — mã hóa (encryption), masking, và tokenization — mỗi lớp chống một mối đe dọa khác nhau.
Điểm dễ nhầm nhất: ba kỹ thuật này không thay thế nhau. Mã hóa bảo vệ dữ liệu khi đĩa bị đánh cắp hoặc gói tin bị nghe lén, nhưng người có quyền đọc DB vẫn thấy dữ liệu gốc. Masking che dữ liệu khi con người/ứng dụng nhìn vào, nhưng dữ liệu gốc vẫn nằm nguyên đâu đó. Tokenization thay thế dữ liệu gốc bằng giá trị vô nghĩa, kéo dữ liệu thật ra khỏi hệ thống của bạn. Một ngân hàng thật dùng cả ba, đặt đúng chỗ. Bài này đi qua từng lớp, so sánh, và chỉ chỗ dùng trong bối cảnh che số thẻ, số CCCD của NCB.
Mã hóa at-rest và in-transit
Mã hóa (encryption) biến dữ liệu gốc (plaintext) thành chuỗi không đọc được (ciphertext) bằng một thuật toán và một khóa (key). Không có khóa thì ciphertext là rác. Có hai trạng thái dữ liệu cần bảo vệ:
At-rest — khi dữ liệu nằm im trên đĩa. Mối đe dọa: ai đó lấy được ổ cứng, ảnh backup, hoặc file dump. Các mức áp dụng, từ thô đến tinh:
- Mã hóa toàn đĩa (full-disk / storage-level): OS hoặc phần cứng mã hóa cả volume. Trong suốt với ứng dụng, nhưng chỉ chống mất đĩa vật lý — khi máy đang chạy, dữ liệu đã giải mã sẵn cho mọi process.
- TDE (Transparent Data Encryption) ở tầng DB: engine (SQL Server, Oracle, Postgres qua extension, v.v.) mã hóa file dữ liệu và log. "Transparent" nghĩa là ứng dụng không cần đổi code — DB tự mã/giải khi ghi/đọc trang. TDE chống mất file DB và backup, nhưng không chống DBA đọc bảng: ai kết nối được với quyền SELECT vẫn thấy plaintext.
- Mã hóa mức cột / mức trường (column-level): chỉ mã cột nhạy cảm (ví dụ
national_id,pan). Dữ liệu trong cột đó là ciphertext ngay cả với người có quyền SELECT — muốn đọc phải có khóa. Đây là lớp chống chính DBA/insider, đổi lại mất khả năng index/join/tìm kiếm trên cột đó (trừ khi dùng kỹ thuật đặc biệt).
Nguyên tắc: TDE là sàn tối thiểu (gần như bắt buộc trong ngân hàng), còn dữ liệu Restricted thật sự nhạy nên có thêm mã hóa cột hoặc tokenization.
In-transit — khi dữ liệu di chuyển trên mạng. Mối đe dọa: nghe lén (sniffing), man-in-the-middle. Giải pháp chuẩn là TLS (Transport Layer Security) — mọi kết nối client↔DB, service↔service, API đều phải qua TLS (tối thiểu TLS 1.2, khuyến nghị 1.3). Trong ngân hàng, bật sslmode=require/verify-full cho kết nối Postgres, mTLS (mutual TLS) giữa các microservice, và cấm hoàn toàn cổng plaintext. Đừng nhầm HTTPS ở edge là đủ — lưu lượng nội bộ trong VPC cũng cần mã hóa (mô hình zero-trust).
Đối xứng vs bất đối xứng — dùng ở đâu
| Đối xứng (symmetric) | Bất đối xứng (asymmetric) | |
|---|---|---|
| Khóa | Một khóa chung mã & giải | Cặp khóa: public (mã) + private (giải) |
| Thuật toán tiêu biểu | AES-256 (GCM) | RSA-2048/4096, ECC |
| Tốc độ | Rất nhanh | Chậm hơn ~100–1000 lần |
| Dùng cho | Mã khối dữ liệu lớn (file, cột, disk) | Trao đổi khóa, chữ ký số, mã lượng nhỏ |
Thực tế hầu như luôn lai (hybrid): dùng bất đối xứng để trao đổi/bảo vệ một khóa đối xứng, rồi dùng khóa đối xứng đó mã khối dữ liệu lớn (nhanh). TLS handshake chính là ví dụ kinh điển của mô hình lai này. Trong mã hóa dữ liệu lưu trữ, mô hình lai đó được đóng gói thành envelope encryption (phần dưới).
Quản lý khóa — phần khó nhất
Mã hóa mạnh đến đâu cũng vô nghĩa nếu khóa lộ hoặc mất. Quản lý khóa (key management) thường là điểm yếu thật sự, không phải thuật toán. Các trụ cột:
KMS (Key Management Service): dịch vụ tập trung tạo, lưu, xoay, thu hồi khóa (AWS KMS, Azure Key Vault, GCP KMS, HashiCorp Vault). Ứng dụng không giữ khóa gốc — nó gọi KMS để mã/giải hoặc để lấy khóa dữ liệu tạm thời.
HSM (Hardware Security Module): thiết bị phần cứng chuyên dụng, chống can thiệp vật lý, sinh và giữ khóa gốc không bao giờ rời khỏi thiết bị. Ngân hàng dùng HSM (đạt chuẩn FIPS 140-2/140-3) cho khóa PIN, khóa thẻ, khóa gốc của KMS. Đây là yêu cầu của nhiều quy định thanh toán.
Envelope encryption: thay vì mã dữ liệu trực tiếp bằng khóa gốc, ta dùng hai tầng khóa:
- DEK (Data Encryption Key): khóa đối xứng mã dữ liệu thật. Mỗi bảng/tệp/khối có thể có DEK riêng.
- KEK / Master Key: khóa "gói" (wrap) DEK. KEK nằm trong KMS/HSM, không bao giờ lộ ra ngoài.
Dữ liệu được lưu kèm DEK đã bị mã (wrapped DEK). Khi cần đọc: gửi wrapped DEK lên KMS → KMS dùng KEK giải ra DEK → ứng dụng dùng DEK giải dữ liệu → hủy DEK khỏi bộ nhớ. Lợi ích: khối dữ liệu lớn được mã bằng DEK nhanh (đối xứng), còn KEK — thứ quý nhất — không bao giờ chạm dữ liệu và không rời KMS. Xoay KEK chỉ cần mã lại các wrapped DEK (nhỏ), không phải mã lại toàn bộ dữ liệu.
Key rotation (xoay khóa): khóa phải được thay định kỳ (ví dụ KEK mỗi năm, hoặc ngay khi nghi lộ). Envelope encryption khiến việc này rẻ. Cần giữ được nhiều phiên bản khóa để giải dữ liệu cũ trong lúc dữ liệu mới dùng khóa mới.
Tách quyền (separation of duties): đây là điểm governance cốt lõi. Người quản khóa (đội security/KMS admin) không được có quyền đọc dữ liệu, và người có quyền đọc dữ liệu (DBA) không được truy cập khóa gốc. Chỉ khi kết hợp cả hai — thứ mà một cá nhân không nên có — mới đọc được plaintext. Kèm theo dual control (cần hai người phê duyệt) cho thao tác khóa quan trọng. Nguyên tắc này liên kết chặt với kiểm soát truy cập.
Data masking: tĩnh vs động
Mã hóa bảo vệ dữ liệu khỏi hạ tầng bị xâm phạm. Masking giải bài toán khác: cho phép người/hệ thống dùng dữ liệu mà không thấy giá trị nhạy cảm thật. Kết quả sau masking thường vẫn "trông giống thật" (giữ định dạng) nhưng không phải giá trị gốc. Có hai kiểu, khác nhau về khi nào dữ liệu bị che:
Static Data Masking (SDM) — che một lần, tạo bản sao. Khi copy dữ liệu production sang môi trường non-prod (dev, test, UAT, training), ta chạy job masking để tạo bản sao đã che vĩnh viễn. Dev query bảng đó thấy full_name = 'Nguyen Van A' thành 'Khach Hang 0042', số tài khoản bị xáo. Dữ liệu gốc không có mặt trong non-prod. Đây là cách hợp pháp để có dữ liệu test giống thật — nhớ lại từ bài trước: copy nguyên bảng khách hàng sang sandbox là vi phạm Nghị định 13. SDM giải quyết chính bài toán đó.
Yêu cầu quan trọng của SDM là nhất quán tham chiếu (referential consistency): cùng một customer_id phải masking ra cùng một tên giả ở mọi bảng, nếu không join sẽ vỡ. Vì thế masking thường dùng hàm tất định (deterministic) theo khóa.
Dynamic Data Masking (DDM) — che lúc truy vấn, theo vai trò. Dữ liệu gốc vẫn nằm nguyên trong DB. Khi truy vấn, một lớp policy che kết quả tùy vai trò người gọi: teller thấy **** **** **** 1234, còn hệ thống thanh toán (có quyền) thấy PAN đầy đủ. Không nhân bản dữ liệu, che tại chỗ theo thời gian thực. Nhiều DB/tầng trung gian hỗ trợ DDM qua policy hoặc masking view.
| Static (SDM) | Dynamic (DDM) | |
|---|---|---|
| Khi che | Lúc sao chép dữ liệu | Lúc truy vấn |
| Dữ liệu gốc trong hệ thống đích | Không còn | Vẫn còn (che khi trả về) |
| Dùng cho | Non-prod: dev, test, training | Prod: theo vai trò người dùng |
| Rủi ro lộ gốc | Rất thấp (gốc không có mặt) | Cao hơn (policy sai = lộ) |
| Ảnh hưởng hiệu năng | Một lần khi copy | Mỗi query |
Tokenization và phạm vi PCI-DSS
Tokenization thay giá trị nhạy cảm bằng một token không có ý nghĩa toán học liên hệ với gốc (khác mã hóa, vốn có quan hệ thuật toán reversibile bằng khóa). Ánh xạ token↔giá trị gốc được giữ trong một token vault cô lập, bảo vệ nghiêm ngặt. Ví dụ PAN thẻ 9704 1234 5678 9010 → token tok_8f3a... lưu khắp hệ thống; muốn lấy PAN thật, ứng dụng gọi vault (detokenize) với quyền và audit.
Vì sao tokenization được ưa dùng cho số thẻ: giảm phạm vi PCI-DSS (scope reduction). PCI-DSS (chuẩn bảo mật dữ liệu thẻ thanh toán) áp dụng cho mọi hệ thống lưu/xử lý/truyền PAN. Nếu 20 hệ thống của bạn đều đụng PAN thật, cả 20 nằm trong phạm vi kiểm toán — cực đắt. Với tokenization, chỉ token vault (và ít hệ thống thật sự cần PAN) nằm trong phạm vi; 18 hệ thống còn lại chỉ thấy token vô hại nên rơi ra khỏi phạm vi. Chi phí và rủi ro tuân thủ giảm mạnh.
Format-Preserving Encryption (FPE) là biến thể: mã hóa nhưng giữ nguyên định dạng — mã một PAN 16 số ra một chuỗi 16 số hợp lệ, mã CCCD ra 12 số. Nhờ vậy dữ liệu vừa với schema/độ dài cột cũ, không phải đổi cấu trúc bảng hay ứng dụng legacy. FPE (chuẩn NIST FF1/FF3) là mã hóa (reversibile bằng khóa, không cần vault), nên nó nằm giữa tokenization và mã hóa cổ điển. Dùng khi cần giữ định dạng nhưng không muốn vận hành một vault.
So sánh ba kỹ thuật
| Tiêu chí | Mã hóa (encryption) | Masking | Tokenization |
|---|---|---|---|
| Bản chất | Biến đổi thuận nghịch bằng khóa | Che/thay bằng giá trị giả | Thay bằng token, gốc để trong vault |
| Đảo ngược | Có, nếu có khóa | Thường không (một chiều) | Có, qua vault (có quyền) |
| Giữ định dạng | Không (trừ FPE) | Thường có | Thường có |
| Giữ được join/analytics | Khó (trừ deterministic/FPE) | Có nếu nhất quán tham chiếu | Có (token nhất quán) |
| Bảo vệ khỏi | Mất đĩa, nghe lén, insider (mức cột) | Người dùng non-prod / theo vai trò | Kéo dữ liệu thật ra khỏi hệ thống |
| Điểm yếu chính | Quản lý khóa | Policy sai (DDM) / rò gốc | An toàn của vault |
| Chỗ dùng điển hình | At-rest/in-transit, cột nhạy | Non-prod, hiển thị theo vai trò | PAN thẻ, giảm phạm vi PCI |
Quy tắc chọn nhanh: cần đọc lại giá trị gốc và đó là số thẻ → tokenization; cần bảo vệ hạ tầng/kho → mã hóa; cần cho người dùng thấy dữ liệu che → masking. Chúng chồng lớp: PAN có thể được tokenize, vault thì mã hóa at-rest, kết nối thì TLS, và màn hình teller thì masking hiển thị 4 số cuối.
Che dữ liệu bằng SQL — minh họa trên sandbox
Trên sandbox Postgres read-only, ta minh họa dynamic masking đơn giản kiểu hiển thị cho cột account_no — che phần giữa, chỉ để lộ vài ký tự cuối. Đây là masking hiển thị (presentation masking), không phải giải pháp bảo mật hoàn chỉnh, nhưng cho thấy đúng ý tưởng che tại tầng truy vấn.
Che bằng substring — chỉ lộ 4 ký tự cuối:
-- ▶ Chạy được
SELECT
id,
account_no,
'****' || substring(account_no FROM length(account_no) - 3) AS masked_account_no,
currency
FROM accounts
ORDER BY id
LIMIT 20;
Che bằng regexp_replace — thay mọi chữ số trừ 4 ký tự cuối bằng dấu * (giữ nguyên độ dài, giống FPE về mặt định dạng hiển thị):
-- ▶ Chạy được
SELECT
id,
account_no,
regexp_replace(account_no, '.(?=.{4})', '*', 'g') AS masked_account_no
FROM accounts
ORDER BY id
LIMIT 20;
Cả hai chỉ đọc cột accounts.account_no nên chạy được trên sandbox. Trong hệ thống thật, logic này được đặt vào masking view hoặc policy DDM và chỉ áp cho vai trò không có quyền xem đầy đủ — vai trò thanh toán vẫn SELECT account_no gốc.
Use case thực tế
Bối cảnh: NCB triển khai một hệ thống phân tích hành vi chi tiêu trên dữ liệu thẻ. Ban đầu, đội định copy nguyên bảng card_transactions (chứa PAN đầy đủ) sang kho phân tích và môi trường dev. Đội governance chặn lại: như vậy kéo cả kho phân tích, dev, và 6 dashboard vào phạm vi PCI-DSS, đội kiểm toán ước tính thêm ~40 hệ thống in-scope.
Kiến trúc lại theo ba lớp:
- Tokenization tại nguồn. Trước khi PAN rời hệ thống thẻ (in-scope), một service tokenize thay PAN bằng token nhất quán (cùng PAN → cùng token, để vẫn nhóm được giao dịch theo thẻ). Token vault + HSM là hệ thống duy nhất giữ PAN thật.
- Kho phân tích chỉ nhận token. Analyst nhóm chi tiêu theo
card_token, tính tần suất, giá trị trung bình — không cần PAN thật. Kho này rơi ra khỏi phạm vi PCI. Số hệ thống in-scope giảm từ ~40 xuống 3. - Static masking cho môi trường dev. Bản dev dùng SDM: token vẫn giữ (an toàn), nhưng
full_name,citycủa khách được thay bằng giá trị giả nhất quán để join không vỡ. Không dữ liệu định danh thật trong dev. - Mã hóa + TLS bao quanh. Vault mã hóa at-rest bằng envelope encryption (KEK trong HSM); mọi kết nối detokenize qua mTLS; DEK xoay hằng năm.
- Dynamic masking ở màn hình nghiệp vụ. App chăm sóc khách hàng hiển thị
**** **** **** 1234cho nhân viên tổng đài; chỉ vai trò tra soát gian lận, sau phê duyệt, mới detokenize được PAN đầy đủ — mỗi lần đều ghi audit.
Kết quả: Phạm vi PCI-DSS giảm ~92% (40 → 3 hệ thống), chi phí kiểm toán và bề mặt rủi ro giảm tương ứng; analyst vẫn phân tích được đầy đủ; không còn dữ liệu thẻ/định danh thật trong non-prod. Chi phí thực chất là chuẩn hóa một service tokenization dùng chung và vận hành vault — rẻ hơn nhiều so với kiểm toán 40 hệ thống mỗi năm. Nhãn phân loại từ bài trước chính là thứ chỉ ra cột nào cần đi qua quy trình này.
Ghi nhớ
- Ba kỹ thuật, ba mối đe dọa khác nhau, dùng chồng lớp: mã hóa chống mất hạ tầng/nghe lén; masking chống lộ khi người/ứng dụng nhìn; tokenization kéo dữ liệu thật ra khỏi hệ thống. Không cái nào thay được cái nào.
- At-rest: full-disk (chống mất đĩa) < TDE (chống mất file DB, nhưng DBA vẫn đọc) < mã hóa cột (chống cả insider). In-transit: luôn TLS 1.2+, kể cả lưu lượng nội bộ.
- Đối xứng (AES) mã khối lớn nhanh; bất đối xứng (RSA/ECC) trao đổi khóa/chữ ký. Thực tế luôn lai — envelope encryption đóng gói mô hình này.
- Envelope encryption: DEK mã dữ liệu, KEK (trong KMS/HSM) wrap DEK. KEK không bao giờ rời KMS; xoay KEK rẻ vì chỉ mã lại các wrapped DEK.
- Điểm yếu thật là quản lý khóa, không phải thuật toán. Bắt buộc tách quyền quản khóa vs quản dữ liệu, key rotation định kỳ, HSM cho khóa gốc.
- Static masking = che một lần khi copy sang non-prod (giải bài toán "không được copy dữ liệu thật"); phải nhất quán tham chiếu. Dynamic masking = che lúc query theo vai trò, gốc vẫn nằm trong DB.
- Tokenization giảm phạm vi PCI-DSS vì hệ thống chỉ thấy token thì rơi ra khỏi phạm vi kiểm toán. FPE giữ định dạng, không cần vault, nhưng là mã hóa thuận nghịch bằng khóa.
- Trên sandbox có thể minh họa masking hiển thị
account_nobằngsubstring/regexp_replace; ngoài thực tế đặt vào masking view/policy DDM chỉ áp cho vai trò không đủ quyền.
Bài viết liên quan
CSV/JSON/Parquet/Avro, lưu trữ theo hàng vs cột, nén, và OLTP vs OLAP.
Data Engineering là gì, vai trò trong vòng đời dữ liệu, và bức tranh hệ sinh thái công cụ.
Vì sao xử lý phân tán, mô hình Spark (RDD/DataFrame), lazy evaluation, shuffle và tối ưu.
Đảm bảo chất lượng & minh bạch dữ liệu bằng dbt: data tests dựng sẵn (unique, not_null, relationships, accepted_values), singular test, unit test, và tài liệu tự sinh kèm lineage graph.