App: chat bảo mật với TLS handshake và PKI
Xây app chat bảo mật: mô phỏng bắt tay TLS, mã hóa đối xứng phiên, chữ ký PKI, demo tấn công MITM bị chặn.
Chuyên giaThuật toán ~120 phút
Ôn lại trước khi học
Giới thiệu
Bài này xây app chat mã hóa như Zalo bảo mật. Kẻ nghe lén chỉ thấy ký tự rác.
Kiến thức cần nhớ
Bắt tay TLS trao khóa
- Client chào, server gửi chứng chỉ, client verify rồi trao khóa.
- RSA mã hóa tiền khóa, ECDH cùng suy ra khóa phiên.
- Xong handshake hai bên có chung 1 khóa phiên.
- Ví dụ đời thường: 2 người thống nhất mật khẩu riêng giữa chợ đông.
PKI xác thực danh tính
- CA gốc ký chứng chỉ gắn khóa công khai với tên miền.
- Client verify chữ ký, tên miền và hạn sử dụng.
- Chứng chỉ giả không do CA ký bị cắt ngay.
- Bỏ qua verify là mở cửa cho kẻ giả mạo.
Kênh chat mã hóa
- Tin nhắn mã hóa đối xứng AES-GCM bằng khóa phiên.
- Nonce tăng dần chống gửi lại bản mã cũ.
- Tag chống sửa lén, sai tag thì vứt tin.
- Server trung chuyển chỉ thấy bản mã, không đọc được.
Ví dụ
- Input: 2 client handshake rồi chat 20 tin. Output: nội dung đúng, server log toàn bản mã.
- Giải thích: chỉ 2 đầu có khóa phiên nên chỉ họ giải được.
- Input: kẻ MITM chen vào với chứng chỉ giả. Output: client từ chối, cắt trước tin đầu tiên.
- Giải thích: chữ ký không về CA gốc nên verify thất bại.
💻 Bài tập
Ngôn ngữ: Python 3 với ssl, socket/asyncio, cryptography. Nộp vào day-142-secure-chat/.
Đây là bài học. Không tự thiết kế giao thức mật mã cho sản phẩm thật. Không commit khóa riêng vào repo (thêm vào
.gitignore).Bài 1: Chat qua TLS
- Tạo CA riêng, cấp chứng chỉ cho
localhost(dùng lại ngày 106). - Server
asyncionhận nhiều client, phát tin nhắn cho mọi người. Dùngssl.SSLContextvới TLS 1.3. - Client bắt buộc kiểm tra chứng chỉ bằng CA riêng và kiểm tra hostname.
Client dùng CA đúng -> kết nối được, chat được
Server dùng chứng chỉ tự ký khác -> client từ chối với lỗi CERTIFICATE_VERIFY_FAILED
Chứng chỉ hết hạn -> client từ chối
Dùng Wireshark hoặc tcpdump bắt gói: chỉ ra nội dung tin nhắn không đọc được.
Bài 2: Mã hóa đầu cuối giữa 2 người
TLS chỉ bảo vệ tới server. Thêm lớp mã hóa đầu cuối:
- Mỗi client sinh cặp khóa X25519. Server chỉ chuyển khóa công khai.
- Hai client dùng ECDH suy ra khóa chung, qua HKDF thành khóa AES-256-GCM.
- Nonce 12 byte = 4 byte ngẫu nhiên cố định mỗi phiên + 8 byte bộ đếm tăng dần.
- Người nhận từ chối tin có bộ đếm không tăng (chống phát lại) và tin sai tag.
Server in log tin nhắn -> chỉ thấy bản mã
Sửa 1 byte bản mã -> người nhận vứt tin, báo "sai tag"
Gửi lại tin cũ -> người nhận vứt tin, báo "phát lại"
Bài 3: Tấn công MITM (nâng cao)
- Viết proxy MITM đứng giữa, tự tạo chứng chỉ giả cho
localhost. Client kiểm tra đúng thì từ chối. Tắt kiểm tra (verify_mode = CERT_NONE) thì bị đọc lén. Ghi lại cả 2. - MITM ở lớp E2E: server độc hại tráo khóa công khai. Thêm xác minh vân tay: 2 người so 6 chữ số từ hash của 2 khóa công khai. Chỉ ra vân tay khác nhau khi bị tráo.
✅ Tiêu chí hoàn thành
- 3 test chứng chỉ pass.
- Có ảnh chụp gói tin mã hóa.
- E2E chống sửa và chống phát lại, có test.
- Bài 3 tái hiện được MITM khi tắt kiểm tra, và phát hiện tráo khóa bằng vân tay.
❓ Câu hỏi ôn tập
- Handshake TLS 4 bước gồm những gì?
- PKI gắn khóa công khai với danh tính thế nào?
- Nonce chống tấn công gửi lại ra sao?
- Vì sao verify chứng chỉ là bắt buộc?
🌕 Bạn đã hoàn thành ngày 142. Làm hết bài tập phía trên rồi sang ngày tiếp theo.