𝗖𝗕𝗖 𝗕𝗶𝘁 𝗙𝗹𝗶𝗽𝗽𝗶𝗻𝗴 𝗘𝘅𝗽𝗹𝗮𝗶𝗻𝗲𝗱
Encryption does not mean your data is safe from tampering.
Many developers make this mistake. They think if an attacker cannot read the data, they cannot change it. This is wrong. Cryptography treats secrecy and integrity as two different tasks.
The CBC Bit Flipping attack proves this. An attacker can change your data without knowing your secret key.
Here is how it works:
AES does not encrypt data in one large piece. It breaks data into 16-byte blocks. In CBC mode, these blocks chain together. The encrypted output of the first block mixes into the plaintext of the second block.
This chain creates a weakness during decryption. To get the original text of Block 2, the server decrypts it and combines it with the ciphertext from Block 1.
An attacker can exploit this:
- The attacker intercepts your encrypted traffic.
- They do not know the key, so the data looks like gibberish.
- They change specific bits in the ciphertext of Block 1.
- They send this altered data to your server.
- When the server decrypts it, the change in Block 1 shifts the math for Block 2.
The attacker does not need to read the message. They just flip bits to change the final result.
Consider an old web app using encrypted cookies for sessions. A cookie might hold: userid=994;role=user;
An attacker intercepts this cookie and flips bits in the ciphertext. They send many requests until the server accepts one. Because the server only checks if the data decrypts, it processes the modified text. Suddenly, the decrypted string reads: userid=994;role=admi;
The attacker now has admin access. They never read the key or the original cookie.
The mistake is assuming encryption guarantees integrity.
- Confidentiality stops people from reading data.
- Integrity stops people from changing data.
To fix this, use Authenticated Encryption like AES-GCM. It creates a cryptographic tag. This tag acts like a seal. If an attacker changes even one bit, the seal breaks. The server rejects the data immediately.
If you must use CBC, use an Encrypt-then-MAC architecture. Create an authentication code for the ciphertext and verify it before you start decryption.
Secret data is not always trustworthy data. Always prove your data is unchanged before you use it to make decisions.
Giải thích về CBC Bit-Flipping: Tại sao chỉ mã hóa thôi là chưa đủ để đảm bảo tính toàn vẹn
Khi chúng ta nói về mật mã học, chúng ta thường nghĩ đến việc giữ cho dữ liệu bí mật. Chúng ta muốn đảm bảo rằng nếu một kẻ tấn công đánh chặn được dữ liệu, họ sẽ không thể đọc được nội dung bên trong. Đây chính là tính bảo mật (confidentiality).
Tuy nhiên, có một khía cạnh quan trọng khác của an ninh thông tin mà nhiều người thường bỏ qua: tính toàn vẹn (integrity). Tính toàn vẹn đảm bảo rằng dữ liệu không bị thay đổi trái phép trong quá trình truyền tải hoặc lưu trữ.
Một sai lầm phổ biến là tin rằng nếu dữ liệu đã được mã hóa, nó sẽ an toàn trước mọi sự can thiệp. Bài viết này sẽ giải thích tại sao điều đó không đúng thông qua một kỹ thuật tấn công gọi là CBC Bit-Flipping.
Chế độ CBC hoạt động như thế nào?
Chế độ Cipher Block Chaining (CBC) là một phương thức mã hóa khối (block cipher mode) phổ biến. Trong CBC, mỗi khối bản rõ (plaintext block) được kết hợp (XOR) với khối bản mã (ciphertext block) trước đó trước khi được mã hóa.
Công thức toán học cho việc giải mã một khối $P_n$ là: $$P_n = D_k(C_n) \oplus C_{n-1}$$
Trong đó:
- $P_n$ là khối bản rõ hiện tại.
- $D_k$ là hàm giải mã với khóa $k$.
- $C_n$ là khối bản mã hiện tại.
- $C_{n-1}$ là khối bản mã trước đó.
Đối với khối đầu tiên ($P_1$), vì không có khối bản mã trước đó, chúng ta sử dụng một giá trị gọi là Vector khởi tạo (Initialization Vector - IV): $$P_1 = D_k(C_1) \oplus IV$$
Tấn công Bit-Flipping là gì?
Điểm yếu nằm ở phép toán XOR ($\oplus$). Phép toán XOR có một tính chất thú vị: nếu bạn XOR một giá trị với một giá trị khác hai lần, bạn sẽ quay lại giá trị ban đầu.
Trong chế độ CBC, vì $P_n$ được tạo ra bằng cách XOR kết quả giải mã của $C_n$ với $C_{n-1}$, một kẻ tấn công có thể thay đổi một bit trong $C_{n-1}$ để gây ra một thay đổi tương ứng và có thể dự đoán được trong $P_n$.
Cụ thể, nếu kẻ tấn công thay đổi $C_{n-1}$ thành $C'_{n-1}$, thì bản rõ mới $P'n$ sẽ là: $$P'n = P_n \oplus C{n-1} \oplus C'{n-1}$$
Kẻ tấn công không cần biết khóa $k$ hay nội dung thực sự của $P_n$. Họ chỉ cần biết (hoặc đoán được) cấu trúc của bản rõ để thực hiện thay đổi mong muốn.
Một ví dụ thực tế
Giả sử chúng ta có một cookie được mã hóa chứa thông tin quyền hạn của người dùng:
user_id=123;role=guest
Giả sử bản mã của khối đầu tiên (bao gồm cả IV) được gửi đến trình duyệt. Kẻ tấn công muốn thay đổi role=guest thành role=admin.
- Kẻ tấn công xác định vị trí của ký tự
gtrong bản rõ. - Kẻ tấn công tính toán sự khác biệt giữa bit của
gvà bit củaa. - Kẻ tấn công lật các bit tương ứng trong khối bản mã trước đó (hoặc IV nếu
rolenằm ở khối đầu tiên).
Mặc dù việc thay đổi này sẽ làm hỏng khối bản mã trước đó (khiến $P_{n-1}$ trở thành dữ liệu rác), nhưng khối $P_n$ chứa thông tin quan trọng sẽ được thay đổi chính xác theo ý muốn của kẻ tấn công.
Tại sao điều này lại nguy hiểm?
Tấn công Bit-Flipping chứng minh rằng: Mã hóa không đồng nghĩa với tính toàn vẹn.
Một hệ thống có thể cực kỳ bảo mật về mặt nội dung (kẻ tấn công không thể đọc được gì), nhưng lại cực kỳ mong manh về mặt cấu trúc (kẻ tấn công có thể thay đổi ý nghĩa của dữ liệu). Nếu ứng dụng của bạn dựa vào các giá trị được mã hóa để đưa ra các quyết định quan trọng (như quyền quản trị, số dư tài khoản, v.v.) mà không kiểm tra tính toàn vẹn, ứng dụng đó đang gặp nguy hiểm.
Cách phòng tránh
Để ngăn chặn các cuộc tấn công này, bạn không nên chỉ sử dụng mã hóa thuần túy. Thay vào đó, hãy sử dụng các phương pháp sau:
1. Sử dụng Authenticated Encryption (AEAD)
Cách tốt nhất và hiện đại nhất là sử dụng các chế độ mã hóa có xác thực (Authenticated Encryption with Associated Data - AEAD) như AES-GCM hoặc ChaCha20-Poly1305. Các chế độ này kết hợp cả mã hóa và xác thực trong một bước duy nhất, đảm bảo rằng nếu bất kỳ bit nào trong bản mã bị thay đổi, quá trình giải mã sẽ thất bại hoàn toàn.
2. Sử dụng MAC (Message Authentication Code)
Nếu bạn phải sử dụng các chế độ cũ hơn như CBC, hãy áp dụng mô hình Encrypt-then-MAC.
- Đầu tiên, mã hóa bản rõ để tạo ra bản mã.
- Sau đó, tính toán một mã xác thực (như HMAC) trên bản mã đó bằng một khóa riêng biệt.
Khi nhận dữ liệu, trước tiên hãy kiểm tra HMAC. Nếu HMAC không khớp, hãy từ chối dữ liệu ngay lập tức trước khi tiến hành giải mã.
Kết luận
Đừng bao giờ giả định rằng dữ liệu đã được mã hóa là dữ liệu an toàn. Luôn luôn đảm bảo rằng bạn đang bảo vệ cả tính bảo mật và tính toàn vẹn của dữ liệu bằng cách sử dụng các tiêu chuẩn mã hóa hiện đại và có xác thực.
Bài viết này được viết nhằm mục đích giáo dục về an ninh mạng.