Tư duy giải quyết vấn đề (02): Mã hoá tin nhắn trong hệ thống CHAT IM?

Nội dung bài viết

Video học lập trình mỗi ngày

Series Go Backend (Web, App..): Xây dựng Solution Architecture cho app xxxx_CHAT.

Con đường Go Backend: Fresher, Junior...

Bài 1 (Done): Thực hành giải quyết vấn đề về "Tối ưu quy trình xoá dữ liệu tin nhắn trong GROUP

Bật F12 và Soi API


Anh em đã bao giờ thử bật F12 để "soi" API của những app chat lớn như Telegram hay Signal, hoặc dùng Wireshark (Anh em phải biết xài Wireshark nhé) để chặn bắt gói tin chưa? Kết quả anh em nhận được thường chỉ là một đống ký tự "rác" loằng ngoằng, vô nghĩa.

Dù Hacker có đang nằm vùng trong hệ thống mạng, hay thậm chí là chính chúng ta – những người quản trị Backend – nhìn vào Database cũng chỉ biết lắc đầu ngao ngán.

Tại sao họ làm được như vậy? Làm sao để tin nhắn truyền đi an toàn tuyệt đối mà Server không bao giờ biết được nội dung bên trong?

Tiếp nối bài trước về "Tối ưu quy trình xoá dữ liệu tin nhắn trong GROUP", hôm nay chúng ta sẽ bước sang một chương quan trọng không kém để bảo vệ sự riêng tư của 10.000 members.

Kiến trúc Mã hoá và thuật toán Hash.


Đây là phần lý thuyết nền tảng cực kỳ quan trọng để anh em thẩm thấu trước khi chúng ta bắt tay vào thực hành code thực chiến với Golang (Go) – ngôn ngữ "vua" trong việc xử lý concurrency và mã hóa triệu kết nối.

  1. Phân biệt Encryption và Hashing (Đừng để bị "Missing" kiến thức) Trước khi bắt đầu thực hành với Go, anh em phải phân biệt thật rõ hai "vũ khí" này để tránh dùng sai chỗ:

Encryption (Mã hoá): Là quá trình 2 chiều. User A dùng Key mã hóa, gửi qua Server, User B dùng Key giải mã lại nội dung gốc. Nó giống như chiếc Két sắt, có mã số thì mới mở được. Trong Chat, chúng ta dùng AES (đối xứng) để mã hóa nội dung vì nó nhanh "bàn thờ".

Hashing (Băm): Là quá trình 1 chiều. Nó giống như cái Máy ép trái cây, cam đã ép thành nước thì không thể biến ngược lại thành quả cam. Nó dùng để lấy "dấu vân tay" (Signature) của tin nhắn. Nếu hacker sửa dù chỉ 1 dấu phẩy, mã Hash sẽ sai lệch ngay -> Hệ thống sẽ hủy tin nhắn đó lập tức.

Solution Architecture: Luồng mã hoá tin nhắn kiểu Telegram


Tại sao các "ông lớn" như Telegram lại được tin dùng? Cái này theo kinh nghiệm đọc sách báo chứ tôi chưa được xem code của họ nha...

Tôi đoán họ có một kiến trúc phối hợp cực kỳ thông minh giữa tốc độ và bảo mật. Họ không dùng RSA (mã hóa bất đối xứng) cho từng tin nhắn vì nó quá chậm, sẽ làm Server của anh em "đắp chiếu" ngay lập tức khi Group có 10.000 người nhắn tin cùng lúc.

Mô hình này có lẽ đúng nhất cho trường hợp này...

Tại sao tôi thấy nó lại an toàn? Điểm mấu chốt là cái Shared Key (K). Nó chỉ nằm trong bộ nhớ RAM của chính điện thoại User A và B. Server Go của chúng ta chỉ đóng vai trò "thằng chuyển bưu phẩm", nó thấy cái hộp nhưng không bao giờ có chìa khóa để mở. Đây chính là linh hồn của End-to-End Encryption (E2EE).

Tối ưu Backend: Khi nào nên dùng FNV Hash thay vì MD5?


Trong bài trước, mình có nhắc đến việc chia 10.000 member ra nhiều Box (Database Sharding). Để tìm nhanh xem một User thuộc Server nào trong hàng trăm Node, chúng ta cần Hash ID người dùng.

Ở dự án xxxx_CHAT, mình khuyên anh em nên dùng FNV (Fowler-Noll-Vo) Hash:

MD5: Độ bảo mật cao nhưng tốn quá nhiều CPU vì phép toán phức tạp (khoảng 6.8 phép toán/byte).

FNV: Cực kỳ nhẹ, tốc độ xử lý nhanh "bàn thờ" và phân tán dữ liệu rất đều. Rất phù hợp để làm nhiệm vụ điều hướng (Routing) dữ liệu trong các hệ thống Go Backend hiệu năng cao.

Tại sao lại là Golang cho phần thực hành sắp tới?


Anh em chuẩn bị tinh thần, vì ở bài tới mình sẽ hướng dẫn anh em dùng Go để hiện thực hóa kiến trúc này. Tại sao lại là Go?

Thư viện crypto cực chuẩn: Go hỗ trợ AES, SHA, và các thuật toán đường cong Elliptic (ECC) cực kỳ tối ưu. Goroutine: Giúp anh em mã hóa/giải mã hàng nghìn tin nhắn cùng lúc mà không lo nghẽn hệ thống (Blocking).

Performance: Tốc độ thực thi của Go tiệm cận C++, giúp giảm tải tối đa cho Server khi phải xử lý mã hóa liên tục cho 10.000 users.

Anh em thấy đó, bảo mật không chỉ là cài một thư viện rồi "quăng" dữ liệu vào là xong. Nó là sự phối hợp tỉ mỉ: Dùng Hash để xác minh tính toàn vẹn, dùng AES để bảo mật nội dung, và dùng Diffie-Hellman để bảo vệ chìa khóa.

Nhiệm vụ ở bài này là nắm cái architecture mà tôi đã show ở trên. Ở buổi sau, mình sẽ cùng anh em Hands-on Lab với Golang: Code trực tiếp module mã hóa tin nhắn và thuật toán băm để tối ưu database cho xxxx_CHAT.

Hacker có soi được API thì cũng chỉ để "ngắm" cho vui thôi! Chúc Anh em ngày mới vui vẻ hén...

Có thể bạn đã bị missing