1. Asymmetric algorithms: RSA và ECDSA
Mật mã bất đối xứng dùng một cặp khóa: Public Key có thể chia sẻ, Private Key giữ kín.
RSA có thể mã hóa HOẶC ký, tùy cơ chế. ECDSA THÌ chỉ ký. ECDHE: cách tạo private key dùng chung cho 2 server xa lạ.
RSA không phù hợp để mã hóa dữ liệu lớn vì chậm và giới hạn kích thước thông điệp; dữ liệu lớn thường dùng mã hóa đối xứng.
So theo vai trò: RSA-PSS ~ ECDSA là hai lựa chọn ký số. RSA key transport ~ ECDHE là hai cách thiết lập bí mật cho kết nối, nhưng cách hoạt động khác nhau.
RSA mã hóa và giải mã: Dữ liệu thực tế
Mục tiêu: che giấu nội dung. Chạy bằng RSA-OAEP, khóa 2048 bit.
Public key:
1 | -----BEGIN PUBLIC KEY----- |
Private key: (sample thôi nhé :D)
1 | -----BEGIN PRIVATE KEY----- |
1. Câu gốc Hudson muốn gửi:
1 | Hudson chuyển tiền cho Alice 100 dollars |
2. Hudson mã hóa bằng Public Key của Alice (bằng cách nào đó Alice đưa được cho Hudson Public key này):
1 | Câu gốc + Public Key của Alice -> RSA-OAEP -> 256 byte bản mã |
Result:
1 | 0c 9a 21 b2 82 92 5d eb 9f c3 3d 2f 76 5e 34 d7 |
3. Alice giải mã bằng Private Key của mình:
1 | 256 byte bản mã trên + Private Key của Alice |
RSA ký và verify: Dữ liệu thực tế
Mục tiêu: kiểm tra chữ ký và phát hiện câu bị sửa. Chạy bằng RSA-PSS, khóa 2048 bit và SHA-256.
Public key:
1 | -----BEGIN PUBLIC KEY----- |
Private key:
1 | -----BEGIN PRIVATE KEY----- |
1. Câu Hudson muốn ký:
1 | Hudson chuyển tiền cho Alice 100 dollars |
2. SHA-256 tạo hash, tức “dấu vân tay” của câu, chưa phải chữ ký. Kết quả thật, dạng hex:
1 | SHA-256("Hudson chuyển tiền cho Alice 100 dollars", dùng UTF-8) |
3. Ký bằng Private Key:
1 | Câu gốc + Private Key của Hudson |
Result:
1 | de ce 15 3b 7f 79 03 b7 a3 e4 04 0d d7 cc 6d c8 |
4. Alice kiểm tra bằng Public Key của Hudson:
1 | Câu nhận được + chữ ký + Public Key của Hudson |
Giữ nguyên Public Key và chữ ký từ lần chạy local, kết quả:
| Câu Alice nhận được | Verify |
|---|---|
| Hudson chuyển tiền cho Alice 100 dollars | true: chữ ký hợp lệ |
| Hudson chuyển tiền cho Alice 1000 dollars | false: câu bị sửa, hash đổi, chữ ký cũ không còn hợp lệ |
Ký không che giấu câu gốc. Verify kiểm tra chữ ký, không “giải mã chữ ký” để lấy lại câu.
Chữ ký số với ECDSA
ECDSA chỉ ký, không mã hóa. Ví dụ chạy thật với P-256 và SHA-256.
1. Cặp khóa thử nghiệm của Hudson, hiển thị hex. Private Key chỉ hiện đầu/cuối; phần giữa đã lược bỏ, không phải khóa đầy đủ:
1 | Private Key: e35f8f23...7b3e0608 |
2. Câu gốc và hash SHA-256 của nó:
1 | Hudson chuyển tiền cho Alice 100 dollars |
3. Ký bằng Private Key:
1 | Câu gốc + Private Key đầy đủ của Hudson |
Đủ 64 byte chữ ký thật, dạng hex: 32 byte đầu biểu diễn số nguyên gọi là r, 32 byte sau biểu diễn số nguyên gọi là s.
1 | b7 78 07 94 17 35 3a dd 99 5f d3 13 6d 83 fa 65 |
4. Alice verify bằng Public Key ở bước 1:
1 | Câu nhận được + 64 byte chữ ký trên + Public Key của Hudson |
Kết quả chạy thật, giữ nguyên Public Key và chữ ký:
| Câu Alice nhận được | Verify |
|---|---|
| Hudson chuyển tiền cho Alice 100 dollars | true |
| Hudson chuyển tiền cho Alice 1000 dollars | false |
Giống RSA-PSS: Private Key ký, Public Key kiểm tra; chữ ký không che giấu câu gốc. ECDHE là thỏa thuận khóa, không phải ký.
2. Mã hóa đối xứng: AES
Nếu bất đối xứng giống một ổ khóa công khai và một chìa khóa riêng, thì đối xứng giống hai người cùng giữ bản sao của một chìa khóa bí mật.
1 | Dữ liệu gốc + Secret Key → Mã hóa → Dữ liệu đã mã hóa |
AES (Advanced Encryption Standard) là một thuật toán mã hóa đối xứng phổ biến, hỗ trợ khóa 128, 192 hoặc 256 bit.
Điểm mạnh: Rất nhanh, phù hợp để mã hóa lượng dữ liệu lớn như trang web, ảnh, video hoặc file tải xuống.
Câu hỏi còn lại: Làm sao hai bên có được cùng một Secret Key mà không để lộ nó khi truyền qua mạng? Đây là lúc cơ chế trao đổi khóa như ECDHE xuất hiện.
Trong HTTPS, ta thường gặp AES-GCM, không chỉ tên AES:
- AES là thuật toán mã hóa khối.
- GCM là chế độ giúp vừa mã hóa vừa xác thực dữ liệu, phát hiện việc sửa đổi trái phép.
- GCM cần nonce không bị lặp lại với cùng một khóa. Thuật toán mạnh không cứu được cách sử dụng sai.
TLS 1.3 cũng hỗ trợ ChaCha20-Poly1305 cho vai trò mã hóa có xác thực, nên không phải kết nối HTTPS nào cũng dùng AES.
AES mã hóa và giải mã: Dữ liệu thực tế
Chạy thật bằng AES-256-GCM. Khóa dưới đây là dữ liệu minh họa công khai, không dùng cho dữ liệu thật. Các chuỗi byte được hiển thị bằng hex.
1. Đầu vào:
1 | Câu gốc: Hudson chuyển tiền cho Alice 100 dollars |
Key là khóa chung 32 byte. Nonce là giá trị 12 byte cho lần mã hóa này, không được lặp với cùng Key; nó không cần giữ bí mật.
2. Mã hóa:
1 | Câu gốc (UTF-8) + Key + Nonce → AES-256-GCM |
Tag là mã xác thực, dùng để kiểm tra dữ liệu có bị sửa. Nó là một phần của AES-GCM, không phải chữ ký số.
3. Giải mã bằng cùng Key:
1 | Bản mã + Key + Nonce + Tag |
Kết quả chạy thật: khớp câu gốc. Đổi byte đầu bản mã từ 0f thành 0e, giữ nguyên các giá trị khác → lỗi xác thực, không chấp nhận dữ liệu.
3. Hashing: SHA
Hashing giống như lấy dấu vân tay của dữ liệu: đưa một thông điệp vào hàm băm và nhận lại một giá trị có độ dài cố định.
Ví dụ, SHA-256 luôn tạo ra kết quả dài 256 bit, dù đầu vào là một câu ngắn hay một file lớn.
1 | Dữ liệu → SHA-256 → Giá trị hash 256 bit |
SHA-256: Đổi một ký tự, xem kết quả
Kết quả chạy thật với text UTF-8, hash hiển thị bằng hex:
1 | SHA-256("Hudson chuyển tiền cho Alice 100 dollars") |
Không có Key, không có bước giải mã. Thêm một số 0 làm hash đổi; cả hai kết quả vẫn dài 32 byte, tương ứng 64 ký tự hex.
- Cùng đầu vào thì luôn có cùng kết quả.
- Thay đổi rất nhỏ ở đầu vào thường khiến kết quả thay đổi mạnh.
- Hàm băm mật mã được thiết kế để rất khó tìm đầu vào từ hash hoặc tìm hai đầu vào khác nhau có cùng hash.
Hashing không phải mã hóa: Không có Private Key hay Secret Key để “giải mã” hash về dữ liệu ban đầu. Tuy nhiên, nếu đầu vào dễ đoán, người ta vẫn có thể thử từng giá trị rồi so sánh hash.
Và hash không bảo đảm mỗi dữ liệu có một dấu vân tay duy nhất tuyệt đối. Va chạm vẫn tồn tại về mặt toán học; yêu cầu an toàn là việc tìm ra chúng phải không khả thi về mặt tính toán.
Một giới hạn quan trọng: hash đơn thuần không xác thực người gửi. Nếu hacker sửa được cả file lẫn giá trị hash đính kèm, họ có thể tính lại hash cho file giả. Muốn chống việc đó, cần nguồn hash đáng tin cậy, chữ ký số hoặc cơ chế có khóa như HMAC.
Trong TLS 1.3, hàm băm được dùng để tạo hash của dữ liệu bắt tay và làm nền tảng cho HKDF, cơ chế dẫn xuất khóa. Nó hỗ trợ quá trình xác thực và tạo khóa, chứ không trực tiếp mã hóa trang web.
SHA là tên một họ thuật toán, không phải tất cả đều còn an toàn cho mọi mục đích. SHA-256 thuộc SHA-2; không nên nhầm nó với SHA-1, vốn đã bị phá khả năng chống va chạm.
4. Trao đổi khóa: ECDHE
Diffie-Hellman (một biến thể hiện đại là ECDHE) là thuật toán giúp 2 người, ví dụ máy của bạn và Server, tự tạo ra cùng một bí mật chung để dẫn xuất khóa mã hóa đối xứng, mà KHÔNG CẦN gửi bí mật chung đó qua mạng.
Dù hacker có nghe lén và capture lại 100% dữ liệu truyền qua truyền lại, việc tính ra bí mật chung đó vẫn không khả thi về mặt tính toán với các phương pháp tấn công cổ điển hiện biết, nếu dùng tham số đủ mạnh và triển khai đúng. Đây không phải bảo đảm tuyệt đối: Diffie-Hellman tự nó không ngăn được tấn công đứng giữa chủ động (MITM) nếu thiếu xác thực.
ECDHE: Hai bên tính ra cùng bí mật
Chạy thật với P-256, mỗi bên tạo một cặp khóa mới cho lần trao đổi này. Dữ liệu dưới đây ở dạng hex; Private Key chỉ hiện đầu/cuối, tính toán dùng khóa đầy đủ.
1. Hai cặp khóa thử nghiệm:
1 | Hudson: |
2. Trao đổi Public Key:
1 | Hudson gửi Public Key của Hudson → Alice |
3. Mỗi bên tự tính, kết quả thật:
1 | Private Key Hudson + Public Key Alice → ECDH → bí mật phía Hudson: |
Hai bên tính ra cùng 32 byte bí mật, không truyền bí mật đó cho nhau. Đây là đầu vào để dẫn xuất khóa mã hóa, không phải chữ ký hay bản mã. Chữ E cuối trong ECDHE chỉ việc dùng cặp khóa tạm thời cho lần trao đổi.
Ý tưởng cốt lõi: Ví dụ về màu sắc
Hãy tưởng tượng Diffie-Hellman hoạt động giống như việc trộn màu sơn:
1 | [Máy bạn] [Server] |
- Hacker thấy gì trên mạng? Thấy màu Vàng (công khai), màu Cam, màu Lục.
- Tại sao Hacker thua? Trong mô hình minh họa này, từ Cam và Lục rất khó (gần như không thể) bóc tách ngược lại để tìm ra màu Đỏ hay Xanh ban đầu. Vì thiếu màu bí mật, Hacker không dễ pha ra màu Nâu. Màu sơn chỉ là phép ví von; độ an toàn thực tế dựa trên các bài toán khó trong nhóm toán học được chọn.
ECDHE giải thích từng ký tự là gì?
Tên gọi ECDHE ghép từ 3 thành phần:
- DH (Diffie-Hellman): Tên của 2 nhà khoa học công bố cơ chế trao đổi khóa này từ năm 1976.
- EC (Elliptic Curve - Đường cong Elliptic): Thay vì dùng lũy thừa modulo số nguyên lớn như DH truyền thống, ECDHE dùng các phép toán trên điểm của đường cong Elliptic trên trường hữu hạn. Nó đạt mức an toàn tương đương với khóa nhỏ hơn nhiều, giúp giảm lượng dữ liệu trao đổi; hiệu năng CPU còn tùy thuật toán và cách triển khai.
- E (Ephemeral - Ngắn hạn/Tạm thời):
- Mỗi lần bắt tay HTTPS có trao đổi ECDHE mới, mỗi bên tạo một cặp khóa Diffie-Hellman mới và xóa khóa bí mật tạm thời khi không còn cần. Không phải mỗi lần vào web đều tạo kết nối hay bắt tay mới.
- Tác dụng (Forward Secrecy): Dù sau này lộ Private Key dùng để xác thực Server, hacker cũng không thể chỉ dựa vào khóa đó để giải mã lại các phiên ECDHE trong quá khứ, nếu các bí mật tạm thời đã được xóa an toàn.
5. Honor list algo
Bcrypt: Băm mật khẩu
bcrypt được thiết kế để lưu mật khẩu, không phải băm dữ liệu thông thường như SHA-256. Cùng mật khẩu, salt và cost thì kết quả luôn giống nhau.
Hai điểm chính:
- Salt riêng cho mỗi lần tạo hash: Thư viện sinh salt ngẫu nhiên. Cùng mật khẩu
123456nhưng salt khác → chuỗi lưu khác, chống việc dùng chung bảng băm sẵn để dò hàng loạt tài khoản. - Cố tình chậm: Cost điều chỉnh lượng tính toán. Cost
10tương ứng2^10 = 1.024vòng của bước mở rộng khóa; tăng cost thêm 1 thì công việc xấp xỉ gấp đôi. Thời gian thực tế tùy máy, không cố định 100 hay 300 ms.
Lưu một chuỗi gồm cả cấu hình, salt và hash, không cần cột salt riêng. Cấu trúc minh họa, tổng 60 ký tự:
1 | $2b$10$<salt: 22 ký tự><hash: 31 ký tự> |
Salt là 16 byte ngẫu nhiên, được biểu diễn thành 22 ký tự trong chuỗi bcrypt.
Khi đăng nhập:
1 | Mật khẩu vừa nhập + chuỗi bcrypt trong DB |
Salt không cần giữ bí mật. Nó chống tái sử dụng bảng tra cứu giữa các salt khác nhau; cost làm mỗi lần đoán mật khẩu tốn công hơn. Nếu lộ DB, mật khẩu yếu vẫn có thể bị đoán, bcrypt không khiến brute-force trở thành bất khả thi.
Ghép lại: Khi bạn mở một trang HTTPS
Trong một lần bắt tay TLS 1.3 dùng chứng chỉ và ECDHE, các cơ chế phối hợp như sau. Đây là cách tách vai trò để dễ hiểu, không phải thứ tự chính xác của từng gói tin:
- Xác thực Server: Server dùng Private Key tương ứng với Certificate để ký dữ liệu bắt tay, ví dụ bằng ECDSA hoặc RSA-PSS. Trình duyệt kiểm tra chữ ký, chuỗi chứng chỉ và tên miền để xác minh “Tôi đúng là Google, không phải giả mạo”.
- Thỏa thuận bí mật: Hai bên chạy ECDHE để tự suy ra cùng một bí mật chung mà không truyền bí mật đó qua mạng.
- Dẫn xuất khóa: TLS dùng HKDF dựa trên hàm băm như SHA-256 hoặc SHA-384, kết hợp bí mật chung với ngữ cảnh bắt tay để dẫn xuất các khóa. Hai chiều truyền có khóa riêng, không dùng một khóa duy nhất cho mọi việc.
- Truyền dữ liệu: AES-GCM hoặc ChaCha20-Poly1305 mã hóa và xác thực dữ liệu web/video với tốc độ cao.
| Trụ cột | Ví dụ | Vai trò chính |
|---|---|---|
| Mật mã bất đối xứng | RSA-OAEP, RSA-PSS, ECDSA | Mã hóa bằng RSA-OAEP; ký bằng RSA-PSS hoặc ECDSA. Trong TLS 1.3, RSA/ECDSA đảm nhiệm chữ ký, không vận chuyển khóa phiên bằng RSA |
| Mã hóa đối xứng | AES-GCM | Mã hóa và xác thực dữ liệu với tốc độ cao |
| Hashing | SHA-256 / SHA-384 | Tạo dấu vân tay dữ liệu, làm nền tảng cho HMAC và HKDF |
| Trao đổi khóa | ECDHE | Thỏa thuận bí mật chung để dẫn xuất khóa, không gửi bí mật đó qua mạng |
Tóm lại: RSA và ECDSA nằm chung trong trụ cột mật mã bất đối xứng, với chức năng tùy cơ chế; AES bảo vệ dữ liệu lớn; SHA tạo dấu vân tay dữ liệu; ECDHE giúp hai bên thống nhất bí mật chung. Bốn mảnh ghép phối hợp để bảo vệ một kết nối HTTPS.