[Hành trình tự học DevOps] Bài 2. HTTPS - không chỉ là mã hoá
Bài viết được biên soạn dựa trên nội dung video How HTTPS Works - It's Not Just Encryption của LearnThatStack, với mục đích tổng hợp và trình bày lại các khái niệm một cách dễ tiếp cận hơn.
🔐 Chiếc ổ khóa nhỏ trên trình duyệt
Chiếc ổ khóa nhỏ đó — bạn đã nhìn thấy nó hàng nghìn lần.
Bạn từng hướng dẫn người dùng tìm biểu tượng này, từng thiết lập HTTPS cho ứng dụng của mình. Bạn cũng từng gặp những trang báo lỗi màu đỏ, bấm “Proceed anyway” khi chạy localhost rồi tiếp tục công việc.
Nhưng HTTPS thực sự hoạt động như thế nào?
Hầu hết chúng ta thường hình dung nó như thế này:
Browser lấy key của server, dùng key đó để mã hóa dữ liệu, sau đó server giải mã dữ liệu ở đầu bên kia.
Nhưng thực tế không phải như vậy.
HTTPS không chỉ đơn giản là mã hóa dữ liệu.
Chúng ta sẽ tìm hiểu:
- TLS đang bảo vệ dữ liệu của chúng ta như thế nào.
- Certificate và CA giúp browser xác thực server ra sao.
- Khi TLS hoặc certificate bị lỗi, chúng ta debug ở đâu.
Phần 1. TLS đang bảo vệ chúng ta khỏi điều gì?
Trước khi đi vào handshake, chúng ta cần hiểu chính xác TLS đang cố bảo vệ điều gì.
TLS giải quyết ba vấn đề chính.
1.1. Confidentiality — Tính bí mật
Câu hỏi là:
Người khác có thể đọc dữ liệu đang truyền hay không?
Khi bạn gửi một HTTP request, nó không đi thẳng từ laptop đến server.
Nó có thể đi qua:
Laptop
|
Router
|
ISP
|
Internet
|
Server
Bạn không sở hữu và cũng không kiểm soát phần lớn cơ sở hạ tầng này.
Nếu dữ liệu được truyền dưới dạng plaintext, attacker có khả năng quan sát network có thể đọc được những gì bạn gửi.
TLS mã hóa dữ liệu để attacker không thể đọc nội dung của connection.
1.2. Integrity — Tính toàn vẹn
Câu hỏi thứ hai:
Người khác có thể sửa dữ liệu mà bạn không phát hiện ra hay không?
Ví dụ, bạn gửi:
Chuyển 100 USD
Nếu attacker có thể sửa request thành:
Chuyển 1000 USD
mà cả client và server đều không biết thì encryption không còn đủ.
Vì vậy TLS cũng phải đảm bảo:
Dữ liệu nhận được không bị thay đổi mà các bên không phát hiện.
1.3. Authentication — Tính xác thực
Đây mới là phần rất quan trọng.
Câu hỏi thứ ba:
Server mà bạn đang nói chuyện có thực sự là server mà nó tuyên bố hay không?
Giả sử tôi có thể khiến browser của bạn kết nối tới server của tôi thay vì server ngân hàng:
Browser
|
HTTPS
|
v
Attacker
Connection vẫn có thể được mã hóa.
Nhưng bạn đang gửi credential cho attacker.
Vì vậy:
Encryption mà không có authentication thì chưa phải security.
Nó chỉ là:
Privacy dành cho nhầm người.
Hãy ghi nhớ ba mục tiêu này:
Confidentiality + Integrity + Authentication
Đây chính là nền tảng để hiểu toàn bộ TLS.
Phần 2. TLS sử dụng những cơ chế nào?
Bây giờ chúng ta biết TLS cần giải quyết ba vấn đề.
Nhưng để làm được điều đó, TLS không chỉ sử dụng một loại cryptography.
Nó kết hợp nhiều cơ chế khác nhau.
2.1. Symmetric Encryption
TLS sử dụng symmetric encryption để mã hóa dữ liệu thực tế của session.
Với symmetric encryption, hai bên sử dụng cùng một key:
Same Key
|
+----+----+
| |
Encrypt Decrypt
Một bên dùng key để encrypt.
Bên kia dùng chính key đó để decrypt.
AES là một symmetric cipher phổ biến và rất nhanh.
Đây là loại encryption phù hợp để xử lý lượng dữ liệu lớn của một HTTP session.
Về nguyên lý, có thể hình dung encryption giống như một hàm khả nghịch được xây dựng dựa trên một secret key:
secret key -> tạo hàm f
Người nhận có thể đảo ngược phép biến đổi của người gửi để lấy lại plaintext:
- Mã hoá:
Ciphertext = f(Plaintext)
- Giải mã:
Plaintext = f^-1(Ciphertext)
Nhưng chúng ta gặp một vấn đề:
** Để tạo được hàm mã hoá, hai bên phải có cùng một secret key.**
Bây giờ xuất hiện một câu hỏi rất thú vị:
Làm sao hai bên có thể có cùng một secret key mà không gửi secret đó trực tiếp qua network?
2.2. Public-key Cryptography
Public-key Cryptography đươc phát triển vào những năm 1970 để giải quyết vấn đề này.
Trong mô hình Public-key Cryptography, server sở hữu một key pair:
Server Key Pair
|
+-- Public Key -> Client biết
+-- Private Key -> Server giữ
Hai key có quan hệ toán học với nhau, nhưng việc suy ra private key từ public key là không khả thi trong thực tế với các thuật toán an toàn hiện nay. Người ta tận dụng tính chất này để xây dựng thuật toán mã hoá bất đối xứng.
Asymetric encryption
Trong mô hình mã hoá bất đối xứng, client dùng public key của server để mã hóa một secret.
- Client mã hoá:
Encrypted Secret = Encrypt(Public Key, Secret)
- Server giải mã:
Secret = Decrypt(Private Key, Encrypted Secret)
Nhờ vậy, client có thể gửi một secret qua network dưới dạng đã mã hóa mà chỉ server sở hữu private key tương ứng mới có thể giải mã.
Cách này từng được sử dụng trong TLS phiên bản cũ để thiết lập secret, chẳng hạn với RSA key exchange.
Tuy nhiên, asymmetric encryption có chi phí tính toán cao nên không được dùng để mã hóa dữ liệu thực tế của connection.
Digital Signature
Public-key cryptography còn có một công dụng khác là xác thực dành tính server bằng chữ ký số.
Mục đích của digital signature không phải là giữ bí mật dữ liệu, mà là chứng minh:
Server thực sự sở hữu private key tương ứng với public key.
Trong mô hình digital signature, server dùng private key để tạo chữ ký, client dùng public key để kiểm tra:
- Server ký:
Signature = Sign(Private Key, Data)
- Client xác minh:
Valid = Verify(Public Key, Data, Signature)
Nếu chữ ký hợp lệ, client có thể kết luận rằng dữ liệu được ký bởi bên sở hữu private key tương ứng với public key đó.
Trong TLS 1.3, client sử dụng public key của server để xác minh chữ ký của server. Public key này client lấy được từ certificate của server. Certificate cũng giúp browser xác định public key đó thuộc về đúng server/domain cần kết nối.
Vì vậy phân biệt rõ 2 khái niệm:
Public-key Cryptography
|
+-- Asymmetric Encryption -> key exchange trong TLS cũ
+-- Digital Signature -> xác thực danh tính server
Ngày nay, việc thiết lập shared secret key được thực hiện bằng thuật toán ECDHE, sau đó dùng symmetric encryption để bảo vệ dữ liệu.
2.3. ECDHE — Tạo Shared Secret
TLS 1.3 sử dụng:
ECDHE — Elliptic Curve Diffie-Hellman Ephemeral
Ý tưởng quan trọng nhất là:
Hai bên có thể tạo ra cùng một shared secret mà không cần truyền shared secret đó qua network.
Nó giải quyết triệt để bài toán được đặt ra trong mục 2.1.
Attacker có thể nhìn thấy các thông tin được trao đổi.
Nhưng họ không thể thực tế tính ngược ra secret nếu không giải được bài toán toán học phía sau ECDHE.
Hãy hình dung thuật toán ECDHE giống như một trò chơi pha trộn màu sơn công khai.
Bước 1. Alice và Bob thống nhất một màu gốc công khai
G.Bước 2. Mỗi người tự giữ một màu bí mật riêng. Alice giữ màu
a, Bob giữ màub.Bước 3. Hai người trộn màu gốc với màu bí mật của mình rồi gửi cho nhau. Alice gửi màu
aG, Bob gửi màubG. Kẻ trộm chỉ thấy hai hỗn hợp này.Bước 4. Nhận hỗn hợp của đối phương, pha thêm màu bí mật của mình để cùng nhận được một màu cuối cùng
abG.
Màu cuối cùng này chính là Bí mật chung (Shared Secret) dùng để mã hóa dữ liệu.
Tại sao nó an toàn tuyệt đối?
Kẻ trộm dù biết toàn bộ thuật toán, có đủ màu G, aG và bG, nhưng bất khả thi để tách ngược nhằm tìm ra màu bí mật a, b của Alice và Bob.
Do đó, không thế tìm ra được màu bí mật chung.
Security không đến từ việc:
“Giấu thuật toán.”
Mà đến từ:
Một tính chất toán học khiến việc đảo ngược phép tính trở nên bất khả thi về mặt tính toán trong thực tế.
Có một từ rất quan trọng trong ECDHE:
Ephemeral
ECDHE tạo một key pair tạm thời (hai màu tạm thời a, b) cho từng session.
Điều này mang lại:
Forward Secrecy
Giả sử attacker ghi lại traffic của bạn hôm nay.
Nhiều năm sau, private key của server bị đánh cắp.
Với forward secrecy:
Attacker vẫn không thể dùng private key đó — vốn là key tạm thời, để giải mã traffic cũ đã ghi lại.
Đây là một trong những lý do ECDHE rất quan trọng trong TLS hiện đại, và cũng giải thích lý do vì sao nó được sử dụng thay thế cho các thuật toán key change sử dụng Asymmetric Encryption trong các phiên bản TLS cũ.
2.4. Tại sao không dùng Asymmetric Encryption cho toàn bộ dữ liệu?
Các thuật toán asymmetric phù hợp cho những tác vụ như authentication và key agreement, nhưng không hiệu quả khi phải xử lý lượng dữ liệu lớn.
Ví dụ, một thuật toán mã hoá đối xứng AES-128 có thể nhanh hơn một thuật toán mã hoá bất đối xứng RSA-2048 hàng nghìn đến hàng chục nghìn lần khi xử lý dữ liệu, tùy phần cứng và cách đo.
Vì vậy TLS sử dụng mỗi cơ chế cho một nhiệm vụ phù hợp:
1. Xác thực danh tính:
Certificate
|
v
Public-key Cryptography
|
v
Authenticate Server
2. Mã hoá dữ liệu:
ECDHE
|
v
Shared Secret
|
v
Session Keys
|
v
Symmetric Encryption
|
v
HTTPS Data
Nói ngắn gọn:
Public-key Cryptography giúp xác thực server.
ECDHE dùng để thiết lập shared secret.
Symmetric encryption dùng để mã hóa dữ liệu.
Bây giờ chúng ta đã biết từng thành phần làm gì.
Hãy xem chúng phối hợp với nhau trong một TLS handshake.
Phần 3. TLS Handshake step by step
Khi bạn nhập:
https://bank.com
và nhấn Enter, TLS handshake sẽ diễn ra trước khi HTTP request được truyền đi.
Có thể hình dung đơn giản:
Browser Server
| |
|---- Client Hello --->|
|<--- Server Hello ----|
| |
| (Session Keys) |
| |
|---- HTTPS Data ----->|
Bây giờ hãy đi qua từng bước.
3.1. Client Hello
Browser bắt đầu bằng:
Client Hello
Nó thông báo cho server biết những gì client hỗ trợ, chẳng hạn:
- TLS version.
- Cipher suites.
- Client random.
- Client key share.
Bạn có thể hình dung browser đang nói:
“Đây là những công cụ cryptography mà tôi hỗ trợ.”
Client Random là một giá trị ngẫu nhiên được tạo mới cho mỗi connection. Nó sẽ được sử dụng cùng với các thông tin khác để tạo ra session keys.
Client Key Share là phần dữ liệu phục vụ cho quá trình ECDHE key exchange. Với TLS 1.3, client gửi Client Key Share ngay trong Client Hello, giúp hai bên có thể bắt đầu quá trình trao đổi khóa ngay từ những bước đầu tiên.
Sau khi nhận Client Hello, server sẽ lựa chọn các tùy chọn mà cả hai bên cùng hỗ trợ và tiếp tục quá trình thiết lập kết nối bảo mật.
3.2. Server Hello và Certificate
Server phản hồi với những thông tin cần thiết cho handshake:
- Cipher suite được chọn.
- Server random.
- Server key share.
- Certificate
- CertificateVerify
Certificate rất quan trọng vì nó chứa identity và public key của server. Nó trả lời câu hỏi:
"Server này là ai?"
Nhưng có Certificate thôi thì chưa đủ. Bất kỳ ai cũng có thể lấy được certificate công khai của bank.com rồi gửi lại cho bạn, dù không hề sở hữu private key thật. Một câu hỏi khác được đặt ra:
"Server này có thật sự sở hữu private key tương ứng không?
Vì vậy server còn phải gửi kèm CertificateVerify — một chữ ký mới, được tạo ngay lúc handshake bằng chính private key của server. Browser dùng public key lấy từ Certificate để verify chữ ký này.
Nếu khớp, browser mới chắc chắn rằng:
"Server đang nói chuyện thật sự nắm giữ private key, chứ không phải chỉ nhặt được certificate của người khác"
Nhưng vẫn còn một câu hỏi lớn hơn:
"Tôi có nên tin bản thân certificate này không?"
Quá trình kiểm tra này liên quan đến Certificate Authority (CA) và Certificate Chain. Chúng ta sẽ tìm hiểu kỹ hơn ở Phần 4.
3.3. Từ Shared Secret đến Session Keys
Ở mục 3.1 và 3.2, cả Client và Server đều gửi cho nhau một Key Share, hai bên có đủ thông tin cần thiết để thực hiện quá trình ECDHE key exchange.
Nhưng Key Share đó không phải giá trị ngẫu nhiên vô nghĩa — nó được tạo từ một private key tạm thời (ephemeral), và một generator point G mà hai bên đã biết trước (vì đã thống nhất qua tên curve, ví dụ x25519).
Cách tính diễn ra như sau:
Phía Client:
- Chọn một số ngẫu nhiên bí mật: a (Client private key)
- Tính: A = a × G
- Gửi A cho Server → đây là Client Key Share
Phía Server:
- Chọn một số ngẫu nhiên bí mật: b (Server private key)
- Tính: B = b × G
- Gửi B cho Client → đây chính là Server Key Share
Sau khi trao đổi xong, mỗi bên dùng private key của mình kết hợp với key share nhận được từ phía kia để tính ra Shared Secret:
Client tính: a × B = a × (b × G) = (a x b) x G
Server tính: b × A = b × (a × G) = (b x a) x G
Vì phép nhân trên curve có tính chất giao hoán, nên hai kết quả này hoàn toàn giống nhau:
(a × b) × G = (b × a) × G = Shared Secret
Đây là điểm mấu chốt của ECDHE:
Hai bên tự tính ra được cùng một Shared Secret, dù không ai gửi private key của mình đi.
Người đứng giữa (nếu có nghe lén) chỉ thấy được G, A, B — không thể suy ngược ra a, b, hay Shared Secret nếu không giải được bài toán discrete logarithm trên đường cong elliptic.
Vì private key ECDHE được tạo mới cho mỗi connection, đây là tính chất ephemeral và nó là nền tảng tạo nên Forward Secrecy.
Từ Shared Secret đến Session Keys
Shared Secret chưa phải key dùng trực tiếp để mã hóa dữ liệu.
TLS 1.3 sử dụng:
HKDF — HMAC-based Key Derivation Function
cùng với các thông tin của handshake, chẳng hạn Client Random, Server Random đã được đề cập ở mục 3.1 và 3.2 để tạo ra các key cần thiết.
Random là dữ liệu công khai và được tạo mới cho mỗi handshake, giúp các connection có key material khác nhau.
Có thể hình dung đơn giản:
Client Random
+
Server Random
+
Shared Secret
|
v
HKDF
|
v
Session Keys
Tại sao cần nhiều Session Keys?
TLS không dùng một key duy nhất cho toàn bộ connection.
Ít nhất, cần phân biệt key của hai hướng truyền dữ liệu:
Client ---> Server (Client Write Key)
Client <--- Server (Server Write Key)
Lý do là nếu cả hai hướng dùng chung một key, việc phân biệt và bảo vệ dữ liệu theo từng hướng sẽ kém an toàn hơn.
Ngoài ra, TLS 1.3 còn tạo ra các key/secret trung gian cho những giai đoạn khác nhau của handshake và quá trình cập nhật key.
Điểm cần nhớ là:
Random giúp mỗi handshake có key material riêng.
ECDHE tạo ra Shared Secret.
HKDF biến key material thành các key cụ thể mà TLS cần.
Client và Server dùng key riêng cho từng hướng truyền dữ liệu.
3.4. Finished Message và HTTP Request
Sau khi session keys được tạo, handshake vẫn chưa hoàn toàn kết thúc.
Server gửi một:
Finished message
được bảo vệ bằng key vừa tạo.
Client kiểm tra message này.
Nếu hợp lệ, client có thể xác nhận rằng handshake không bị thay đổi và hai bên đã derive key thành công.
Client cũng gửi Finished message của mình.
Khi quá trình này hoàn tất:
TLS handshake đã hoàn thành.
Lúc này HTTP request thực sự được truyền đi:
HTTP Request
|
v
Symmetric Encryption
|
v
Encrypted HTTPS
Đây là điểm quan trọng nhất cần nhớ:
Symmetric encryption xử lý dữ liệu thực tế vì nó nhanh hơn rất nhiều
TLS 1.3 được thiết kế để hoàn thành handshake với một round trip trong trường hợp thông thường, giúp giảm latency so với các phiên bản TLS cũ hơn.
Phần 4. Certificate và CA làm gì?
Đến đây chúng ta đã hiểu cách TLS tạo ra một connection được mã hóa.
Nhưng vẫn còn một câu hỏi quan trọng:
Làm sao browser biết server mà nó đang kết nối là server thật?
Đây chính là vai trò của Certificate và Certificate Authority.
Có sự khác biệt rất lớn giữa:
“Connection được mã hóa.”
và:
“Connection được mã hóa tới đúng server.”
4.1. Certificate Authority — CA
Certificate Authority, viết tắt là CA, là một tổ chức mà browser và operating system đã đồng ý tin tưởng.
Khi bạn muốn có certificate cho domain của mình, bạn phải chứng minh với CA rằng:
Bạn thực sự kiểm soát domain đó.
CA thường yêu cầu bạn thực hiện một trong các cách xác minh:
- Đặt một file tại một URL cụ thể.
- Tạo một DNS record.
Ví dụ:
CA cung cấp mã:
abc123
Bạn tạo:
/.well-known/acme-challenge/abc.txt -> với nội dung abc123
Khi đó file có thể truy cập tại:
https://example.com/.well-known/acme-challenge/abc.txt
CA truy cập URL này. Nếu nhận được đúng nội dung abc123, CA biết rằng bạn có quyền kiểm soát server của example.com và có thể cấp certificate.
CA không cần biết bạn là ai. CA chỉ cần xác minh rằng bạn kiểm soát domain đó.
Sau khi xác minh, CA cấp cho server một certificate. Một certificate bao gồm các thông tin như nơi cấp, cấp cho ai, thời gian hiệu lực và quyền hạn.
Sau đó, CA ký nội dung của certificate bằng private key của CA, và đặt lại chữ ký vào certificate. Do vậy, trong certificate chứa một CA signature (chữ ký).
Khi browser nhận một certificate gửi từ server, việc đầu tiên nó làm là kiểm tra chữ ký. Browser có public key của CA trong trust store được cài đặt sẵn trong OS, nên có thể kiểm tra chữ ký đó trong certificate.
Nếu chữ ký là hợp lệ, browser sẽ tin tưởng toàn bộ nội dung được viết trong certificate.
Domain
|
v
CA xác minh
|
v
CA ký Certificate
|
v
Browser kiểm tra
Điểm quan trọng cần nhớ:
Certificate giúp xác định identity của server.
CA signature giúp browser có cơ sở để tin identity đó.
4.2. Bên trong một X.509 Certificate
Certificate sử dụng format X.509. Bạn chỉ cần quan tâm tới các field chính:
| Field | Ý nghĩa |
|---|---|
| Issuer | CA đã cấp/ký certificate |
| SAN | Hostname/domain mà certificate đại diện |
| Public Key | Public key của server, được chứa trong certificate |
| Validity | Thời gian hiệu lực: Not Before → Not After |
| Key Usage | Các mục đích certificate được phép sử dụng |
| Signature | Chữ ký của CA, dùng để phát hiện certificate bị thay đổi |
Trong đó, SAN — Subject Alternative Name là một field đặc biệt quan trọng.
Nó chứa những hostname/domain mà certificate có thể đại diện.
Ví dụ certificate có thể được cấp cho:
SAN: api.example.com
nhưng bạn lại truy cập:
api.test.com
Certificate có thể hoàn toàn hợp lệ về mặt cryptography nhưng browser vẫn từ chối vì domain không khớp.
Khi gặp lỗi certificate hoặc hostname mismatch, SAN là một trong những thứ đầu tiên cần kiểm tra.
CN (Common Name) trước đây thường được dùng cho hostname, nhưng hiện nay SAN mới là field chính để kiểm tra hostname.
Private key tương ứng với public key trong certificate được server giữ bí mật.
4.3. Certificate Chain
Trong thực tế, Root CA thường không trực tiếp ký tất cả server certificate mà sử dụng các Intermediate CA.
Root CA
|
Intermediate CA
|
Server Certificate
Server certificate được ký bởi Intermediate CA, còn Intermediate CA lại được ký bởi Root CA.
Root CA là phần mà browser hoặc operating system đã tin tưởng từ trước.
Vì vậy browser có thể đi ngược theo chain cho đến Root CA.
Quá trình này có thể được hình dung như sau:
Server cung cấp:
- Server Cert (ký bởi Intermediate CA)
- Intermediate Cert (ký bởi Root CA)
Browser kiểm tra:
- Lấy public key của Intermediate CA trong Intermediate Cert
-> verify Server Cert
- Lấy public key của Root CA trong Trust Store
-> verify Intermediate Cert
Đây gọi là:
Chain of Trust
Nếu một phần của quá trình validation không hợp lệ, certificate có thể bị từ chối.
Phần 5. Khi TLS lỗi, debug ở đâu?
Đến đây chúng ta đã hiểu handshake và certificate.
Bây giờ hãy xem một tình huống rất quen thuộc: HTTPS hoạt động nhưng browser vẫn cảnh báo:
Advanced
|
v
Proceed anyway
Tại sao?
5.1. Self-Signed Certificate
Self-signed certificate là certificate được ký bằng chính private key tương ứng với public key nằm trong certificate đó.
Thông thường:
Server Cert
|
| được ký bởi
v
CA Private Key
Với self-signed:
Server Cert
|
| được ký bởi
v
Server Private Key
Nghĩa là không có CA đứng phía sau certificate.
Self-signed certificate vẫn có thể dùng để thiết lập HTTPS và mã hóa dữ liệu. Vấn đề là browser không mặc định tin certificate này.
Trong môi trường development/testing, để khắc phục điều này, bạn có thể cài certificate vào trust store của client. Trên Linux:
cp server.crt /usr/local/share/ca-certificates/
update-ca-certificates
Sau khi cài certificate vào trust store, browser sẽ tin certificate và không còn cảnh báo.
5.2. Debug Certificate
Khi TLS bị lỗi, hãy kiểm tra những thứ phổ biến trước:
1. SAN
2. Validity
3. Intermediate Certificate
4. Trust Store
SAN — Kiểm tra Domain
Ví dụ certificate dành cho:
api.example.com
nhưng request tới:
api.test.com
→ Domain không khớp với SAN, certificate bị từ chối.
Validity — Kiểm tra Thời hạn
Certificate có thời gian sử dụng:
Not Before -> Not After
Nếu thời điểm hiện tại nằm ngoài khoảng này:
→ Certificate chưa có hiệu lực hoặc đã hết hạn.
Intermediate Certificate — Kiểm tra Certificate Chain
Một lỗi phổ biến là server chỉ gửi server certificate mà không gửi các Intermediate Certificate cần thiết.
Khi đó client có thể không xây dựng được Certificate Chain đầy đủ.
Hãy kiểm tra trực tiếp những certificate mà server gửi:
openssl s_client -connect yourdomain.com:443 -showcerts </dev/null 2>/dev/null | grep -c "BEGIN CERTIFICATE"
Nếu kết quả là:
1
thì server chỉ gửi một certificate.
Trong nhiều trường hợp, điều này có nghĩa server đang gửi server certificate nhưng thiếu intermediate certificate.
Một số browser có thể tự tìm Intermediate certificate, nhưng các client khác như mobile application hoặc một số TLS implementation có thể không làm được và báo certificate error.
Trust Store — Kiểm tra CA có được tin tưởng
Client có một Trust Store chứa danh sách các CA được tin tưởng.
Client kiểm tra Certificate Chain có dẫn tới một Root CA được tin tưởng hay không.
Certificate
|
v
Intermediate CA
|
v
Root CA
|
v
Trust Store
Nếu không tìm được CA đáng tin cậy, certificate bị từ chối.
Phần 6. Tổng kết
Lần tới khi bạn nhìn thấy chiếc ổ khóa HTTPS, hãy nhớ rằng nó chỉ là phần nổi của tảng băng.
Đằng sau nó là cả một quy trình:
Client Hello
|
v
Certificate
|
v
Validation
|
v
ECDHE
|
v
Shared Secret
|
v
HKDF
|
v
Session Keys
|
v
Finished
|
v
Encrypted HTTP
TLS đồng thời giải quyết ba vấn đề:
Confidentiality — Dữ liệu không bị đọc.
Integrity — Dữ liệu không bị sửa mà bạn không biết.
Authentication — Bạn biết mình đang nói chuyện với đúng server.
Mỗi thành phần trong TLS có một chức năng riêng:
- Certificate giúp xác định identity.
- CA giúp browser có cơ sở để tin identity đó.
- ECDHE giúp hai bên tạo shared secret mà không cần truyền secret qua network.
- HKDF giúp hai bên tạo session keys.
- Symmetric encryption bảo vệ dữ liệu thực tế.
Và nhờ ECDHE với ephemeral key, TLS có Forward Secrecy để bảo vệ các session cũ ngay cả khi private key của server bị lộ trong tương lai.
Khi có lỗi, thường không phải:
“TLS bị hỏng một cách bí ẩn.”
Mà thường là một trong các điều kiện kiểm tra certificate không hợp lệ.
Ví dụ:
- SAN không khớp với domain.
- Certificate đã hết hạn.
- Certificate Chain bị thiếu Intermediate.
- CA không được Client tin tưởng.
Khi đã hiểu được flow này, certificate error không còn là một thứ quá bí ẩn nữa.
Bạn có thể bắt đầu hỏi:
“Mắt xích nào đang bị hỏng?”
Và từ đó biết mình cần kiểm tra ở đâu.
Chiếc ổ khóa nhỏ trên browser mà chúng ta nhìn thấy từ đầu chỉ là phần bề mặt của tất cả những cơ chế này.
All rights reserved