𝗖𝗕𝗖 𝗕𝗶𝘁 𝗙𝗹𝗶𝗽𝗽𝗶𝗻𝗴 𝗘𝘅𝗽𝗹𝗮𝗶𝗻𝗲𝗱
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.
อธิบาย CBC Bit-Flipping: ทำไมการเข้ารหัสเพียงอย่างเดียวจึงไม่สามารถรับประกันความถูกต้องของข้อมูล (Integrity) ได้
การเข้ารหัส (Encryption) มักถูกเข้าใจผิดว่าเท่ากับความปลอดภัย แต่มีความแตกต่างที่สำคัญระหว่าง ความลับ (confidentiality) และ ความถูกต้องของข้อมูล (integrity) ในขณะที่การเข้ารหัสช่วยให้มั่นใจว่าบุคคลที่ไม่ได้รับอนุญาตจะไม่สามารถอ่านข้อมูลของคุณได้ แต่มันไม่ได้ป้องกันการ แก้ไข ข้อมูลโดยธรรมชาติ
นี่คือจุดที่ การโจมตีแบบ CBC Bit-Flipping เข้ามามีบทบาท
กลไกการทำงานของโหมด CBC
ในโหมด Cipher Block Chaining (CBC), แต่ละบล็อกของข้อความธรรมดา (Plaintext) จะถูกนำไป XOR กับบล็อกข้อความเข้ารหัส (Ciphertext) ของบล็อกก่อนหน้าก่อนที่จะถูกเข้ารหัส
กระบวนการเข้ารหัสสำหรับบล็อก $i$ คือ: $C_i = E_k(P_i \oplus C_{i-1})$
กระบวนการถอดรหัสสำหรับบล็อก $i$ คือ: $P_i = D_k(C_i) \oplus C_{i-1}$
โดยที่:
- $P_i$ คือบล็อกข้อความธรรมดา (plaintext) ลำดับที่ $i$
- $C_i$ คือบล็อกข้อความเข้ารหัส (ciphertext) ลำดับที่ $i$
- $E_k$ คือฟังก์ชันการเข้ารหัสด้วยคีย์ $k$
- $D_k$ คือฟังก์ชันการถอดรหัสด้วยคีย์ $k$
- $\oplus$ คือการดำเนินการ XOR
- $C_0$ คือ Initialization Vector (IV)
ช่องโหว่: การพลิกบิต (Bit-Flipping)
ช่องโหว่นี้อยู่ที่สมการการถอดรหัส: $P_i = D_k(C_i) \oplus C_{i-1}$
สังเกตว่าบล็อกข้อความธรรมดา $P_i$ ขึ้นอยู่กับบล็อกข้อความเข้ารหัส $C_{i-1}$ ก่อนหน้าโดยตรงผ่านการดำเนินการ XOR หากผู้โจมตีพลิกบิต (flip a bit) ใน $C_{i-1}$ บิตในตำแหน่งเดียวกันนั้นจะถูกพลิกในข้อความธรรมดา $P_i$ ที่ถอดรหัสออกมาด้วยเช่นกัน
แม้ว่าการเปลี่ยน $C_{i-1}$ จะทำให้ข้อความธรรมดาของบล็อก ก่อนหน้า ($P_{i-1}$) กลายเป็นข้อมูลที่อ่านไม่รู้เรื่อง (scrambled) แต่ผู้โจมตีไม่จำเป็นต้องสนใจ $P_{i-1}$ เสมอไป สิ่งที่พวกเขาต้องการคือการควบคุมบิตที่เฉพาะเจาะจงใน $P_i$ เท่านั้น
ตัวอย่างการใช้งานจริง
สมมติว่าแอปพลิเคชันเว็บเก็บข้อมูลบทบาทของผู้ใช้ (user roles) ไว้ในคุกกี้ที่เข้ารหัส:
user_id=123;role=user;
สมมติว่าข้อความนี้ถูกเข้ารหัสโดยใช้โหมด CBC ผู้โจมตีสามารถดักจับข้อความเข้ารหัส (ciphertext) และทราบ (หรือคาดเดาได้) ว่าข้อความนั้นมีคำว่า role=user
ผู้โจมตีต้องการเปลี่ยน role=user เป็น role=admin
- ผู้โจมตีระบุว่าบล็อกข้อความเข้ารหัส $C_{i-1}$ บล็อกใดที่ส่งผลต่อบล็อก $P_i$ ซึ่งมีข้อความ
role=userอยู่ - ผู้โจมตีคำนวณความแตกต่างระหว่าง
userและadmin - ผู้โจมตีทำการพลิกบิตที่สอดคล้องกันใน $C_{i-1}$
เมื่อเซิร์ฟเวอร์ถอดรหัสคุกกี้:
- บล็อก $P_{i-1}$ จะกลายเป็นข้อมูลที่อ่านไม่รู้เรื่อง
- บล็อก $P_i$ จะถอดรหัสออกมาเป็น
role=admin
เซิร์ฟเวอร์อาจจะเพิกเฉยต่อบล็อกที่อ่านไม่รู้เรื่องและดำเนินการต่อด้วยบทบาท role=admin ที่ถูกแก้ไข ซึ่งทำให้ผู้โจมตีได้รับสิทธิ์ระดับผู้ดูแลระบบ (administrator)
วิธีป้องกันการโจมตีแบบ Bit-Flipping
เพื่อป้องกันการโจมตีแบบ Bit-Flipping คุณต้องรับประกันทั้ง ความถูกต้อง (integrity) และ การยืนยันตัวตน (authenticity) การเข้ารหัสเพียงอย่างเดียวไม่เพียงพอ
1. ใช้ Message Authentication Code (MAC)
MAC (เช่น HMAC) คือค่า checksum ทางคริปโทกราฟีที่ถูกแนบไปกับข้อความเข้ารหัส ก่อนการถอดรหัส ผู้รับจะคำนวณค่า MAC ใหม่และเปรียบเทียบกับค่าที่แนบมา หากไม่ตรงกัน แสดงว่าข้อมูลถูกแก้ไข
แนวทางที่แนะนำคือ Encrypt-then-MAC:
- เข้ารหัสข้อความธรรมดาเพื่อให้ได้ข้อความเข้ารหัส (ciphertext)
- คำนวณค่า MAC ของข้อความเข้ารหัส
- แนบค่า MAC ไปกับข้อความเข้ารหัส
2. ใช้ Authenticated Encryption (AEAD)
โหมดการเข้ารหัสสมัยใหม่ เช่น AES-GCM (Galois/Counter Mode) หรือ ChaCha20-Poly1305 ถูกออกแบบมาเพื่อให้ทั้งความลับ (confidentiality) และความถูกต้อง (integrity) ไปพร้อมกัน โหมดเหล่านี้เรียกว่า AEAD (Authenticated Encryption with Associated Data)
หากมีการแก้ไขแม้เพียงบิตเดียวในข้อความเข้ารหัสของ AES-GCM กระบวนการถอดรหัสจะล้มเหลวทั้งหมด ซึ่งช่วยป้องกันไม่ให้ผู้โจมตีทำการพลิกบิตได้สำเร็จ
บทสรุป
การเข้ารหัสให้ความลับ (confidentiality) แต่ไม่ได้รับประกันว่าข้อมูลจะไม่ถูกแก้ไข ในโหมด CBC การโจมตีแบบ bit-flipping ช่วยให้ผู้โจมตีสามารถแก้ไขข้อความธรรมดาได้อย่างแม่นยำ เพื่อสร้างระบบที่ปลอดภัย คุณควรใช้การเข้ารหัสแบบ Authenticated Encryption หรือใช้การเข้ารหัสควบคู่กับ MAC เพื่อรับประกันทั้งความลับและความถูกต้องของข้อมูล