Tìm hiểu TLS fingerprinting hoạt động ra sao, cách JA3 và JA4 phát hiện bot và proxy chặn TLS ở tầng mạng, và cách kiểm tra TLS handshake của chính bạn.
Mỗi kết nối HTTPS đều bắt đầu bằng một lần bắt tay (handshake). Trước khi bất kỳ byte dữ liệu ứng dụng nào được truyền đi, trình duyệt và máy chủ của bạn phải thỏa thuận về các thuật toán mã hóa sẽ dùng — và chính cách trình duyệt của bạn thực hiện cuộc thỏa thuận đó tạo ra một dấu vân tay đặc trưng không kém gì một giá trị băm Canvas hay WebGL. TLS fingerprinting trích xuất chữ ký đó từ quá trình bắt tay để nhận diện phần mềm client đang thực hiện yêu cầu, hoàn toàn không cần dựa vào JavaScript hay cookie. Thấp hơn một lớp, trước cả khi TLS bắt đầu, TCP/IP fingerprinting đã để lộ hệ điều hành của bạn từ quá trình bắt tay TCP; TLS fingerprinting tiếp nối ở tầng mã hóa.
Điểm mấu chốt
- TLS ClientHello chính là dấu vân tay. Khi trình duyệt của bạn mở một kết nối HTTPS, nó gửi một ClientHello liệt kê các cipher suite, extension và đường cong elliptic mà nó hỗ trợ — theo thứ tự do thư viện TLS quyết định, không phải do bạn.
- JA3 băm năm trường trong ClientHello thành một chuỗi MD5 32 ký tự; cùng một phiên bản trình duyệt trên cùng hệ điều hành luôn tạo ra cùng một giá trị băm JA3.
- JA4 cải tiến JA3 với định dạng có thể đọc được bởi con người, có thể sắp xếp, và chịu được việc GREASE ngẫu nhiên hóa cũng như sắp xếp lại extension.
- Các máy chủ kết hợp dấu vân tay TLS với header User-Agent để bắt các bot giả mạo: một yêu cầu tự nhận là Chrome nhưng mang theo handshake của Python
requestslà dấu hiệu cảnh báo ngay lập tức. - Thay đổi dấu vân tay TLS của bạn đòi hỏi phải hoán đổi hoặc tái cấu hình chính thư viện TLS — cài đặt và tiện ích mở rộng của trình duyệt không thể chạm tới nó.
Đang vội? Kiểm tra dấu vân tay TLS trực tiếp của chính bạn — JA4, cipher suite và ClientHello của bạn, đọc thẳng từ kết nối này.
TLS Fingerprinting là gì?
Lưu lượng HTTPS được mã hóa, nhưng quá trình thiết lập thì không. Để tạo lập một phiên mã hóa, client gửi một tin nhắn ClientHello dưới dạng văn bản thường (plaintext), chứa:
- Một trường phiên bản TLS kế thừa (thường là
0x0303; một client TLS 1.3 báo hiệu phiên bản tối đa thực sự của mình trong extensionsupported_versions, mà JA3 không đọc) - Danh sách các cipher suite mà nó sẵn sàng sử dụng, theo thứ tự ưu tiên
- Danh sách các extension (chỉ thị tên máy chủ, các nhóm được hỗ trợ, chia sẻ khóa, ALPN và nhiều hơn nữa)
- Các đường cong elliptic (nhóm được đặt tên) được hỗ trợ để trao đổi khóa
- Các định dạng điểm đường cong elliptic được hỗ trợ
Các trường này do thư viện TLS được liên kết vào ứng dụng quyết định — không phải do người dùng, hệ điều hành, hay tên miền đang được truy cập. Bộ BoringSSL của Chrome, NSS của Firefox, Secure Transport của Safari và các binding OpenSSL của Python đều tạo ra ClientHello khác nhau một cách nhận biết được. TLS fingerprinting đọc những sự khác biệt đó và biến chúng thành một định danh.
Tiêu chuẩn TLS 1.3 (RFC 8446) bắt buộc một tập hợp extension cần thiết, nhưng để lại việc sắp xếp thứ tự các extension tùy chọn và lựa chọn cipher suite từ tập hợp được phép cho phần triển khai — và đó chính xác là nơi các dấu vân tay tồn tại.
JA3: Dấu vân tay đầu tiên được áp dụng rộng rãi
JA3 được các kỹ sư Salesforce (John Althouse, Jeff Atkinson và Josh Atkins) công bố năm 2017 như một cách đơn giản, có thể triển khai được để lấy dấu vân tay client TLS ở tầng mạng mà không cần chạy bất kỳ đoạn code nào trên client. Nó hoạt động bằng cách trích xuất năm trường từ ClientHello và nối chúng thành các giá trị phân tách bằng dấu phẩy:
TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
Các trường có nhiều giá trị được nối bằng dấu gạch ngang. Chuỗi kết quả sau đó được băm bằng MD5 để tạo ra một dấu vân tay 32 ký tự như 769a07eb7f17701dd0ad09b9d04ee785.
Một vài đặc tính làm cho JA3 vừa hữu ích vừa có hạn chế:
Tại sao nó hoạt động: Giá trị băm ổn định giữa các phiên. Cùng phiên bản Chrome trên cùng hệ điều hành luôn tạo ra cùng một JA3 vì thư viện TLS không thay đổi giữa các yêu cầu.
Tại sao nó thất bại: JA3 nắm bắt thứ tự extension và thứ tự cipher, vì vậy một triển khai ngẫu nhiên hóa thứ tự — hoặc một bản cập nhật trình duyệt thêm vào một cipher — sẽ làm thay đổi giá trị băm. Đầu ra MD5 cũng mờ đục: bạn không thể chỉ từ dấu vân tay mà biết liệu nó thuộc về trình duyệt hay thư viện script. Một trình duyệt thêm hỗ trợ cho loại extension mới sẽ thay đổi JA3 của nó dù danh tính cơ bản vẫn như cũ.
JA4: Một thay thế mạnh mẽ hơn
JA4 được giới thiệu bởi FoxIO (bộ công cụ JA4+, do John Althouse dẫn đầu) vào năm 2023 để giải quyết sự dễ gãy của JA3. Thay đổi thiết kế cốt lõi là sắp xếp: cipher suite và extension được sắp xếp theo giá trị số (thập lục phân) trước khi băm, vì vậy việc sắp xếp lại chúng không thay đổi dấu vân tay. Các giá trị GREASE — các điểm code giả dự trữ được rút từ tập hợp điểm code GREASE cố định được định nghĩa trong RFC 8701, mà trình duyệt gửi để giữ cho các thiết bị trung gian không trở nên cứng đờ khi gặp các trường không nhận ra — bị loại bỏ trước khi băm, vì vậy một bản phát hành Chrome làm mới lựa chọn GREASE của nó không làm mất hiệu lực các chữ ký hiện có.
Một dấu vân tay JA4 có một tiền tố có thể đọc được bởi con người theo sau là hai thành phần được băm:
t13d1516h2 _ 8daaf6152771 _ e5627ecdbe6c
│ │ └── SHA-256 rút gọn của các extension đã sắp xếp
│ │ (đã xóa GREASE và SNI) cộng thuật toán chữ ký
│ └────────────────── SHA-256 rút gọn của các cipher suite đã sắp xếp
└───────────────────────────────── tiền tố có thể đọc: t = TLS, 13 = TLS 1.3,
d = SNI có mặt, 15 = số lượng cipher,
16 = số lượng extension, h2 = ALPN (HTTP/2)
Chỉ riêng tiền tố đã cho bạn biết phiên bản TLS, liệu SNI có mặt không, số lượng cipher suite và extension, cũng như ALPN được thỏa thuận — giúp có thể suy luận về dấu vân tay mà không cần cơ sở dữ liệu tham chiếu. Hai hậu tố băm (danh sách cipher, rồi danh sách extension cộng thuật toán chữ ký) sau đó thu hẹp xuống triển khai cụ thể.
JA3 so với JA4: Tổng quan nhanh
| Thuộc tính | JA3 | JA4 |
|---|---|---|
| Định dạng đầu ra | Băm MD5 (32 ký tự, mờ đục) | Tiền tố có thể đọc + hai giá trị băm |
| Nhạy cảm thứ tự | Có — sắp xếp lại thay đổi giá trị băm | Không — giá trị được sắp xếp trước khi băm |
| Xử lý GREASE | Được bao gồm, làm thay đổi băm khi cập nhật | Bị xóa trước khi băm |
| Phiên bản TLS có thể thấy | Không | Có (trong tiền tố) |
| Triển khai từ | 2017 | 2023 |
Trong thực tế, các công cụ bảo mật và mạng CDN biên đang bắt đầu ghi lại cả hai song song.
Có một trường đang bị cả hai thuật toán này thay đổi: trao đổi khóa hậu lượng tử. Các nhóm lai như X25519MLKEM768 đang xuất hiện trong extension supported_groups và key_share của các trình duyệt phổ biến, và vì JA4 sắp xếp trước khi băm còn JA3 thì không, hai thuật toán này hấp thụ thay đổi đó theo cách rất khác nhau — xem ML-KEM thay đổi dấu vân tay ClientHello của bạn ra sao để biết chi tiết.
Giờ bạn đã phân biệt được JA3 và JA4, đây là dữ liệu TLS trực tiếp mà biên (edge) của chúng tôi quan sát được cho kết nối hiện tại của bạn — phiên bản, cipher suite, và (nơi khả dụng) giá trị băm JA3/JA4 — hoàn toàn không lưu trữ gì:
Dấu vân tay TLS trực tiếp của bạn
Đọc từ ClientHello của kết nối này — không lưu trữ bất cứ thứ gì.
Đang đọc bắt tay TLS của bạn…
Hash JA3/JA4 cần kiểm tra gói sâu tại biên; các trường hiển thị là những gì kết nối này để lộ.
Tín hiệu cần theo dõi là sự nhất quán: dấu vân tay của bạn có khớp với trình duyệt mà User-Agent của bạn tuyên bố không? Một sự không khớp — chẳng hạn một lần bắt tay trông giống của Python requests nhưng đứng sau một User-Agent Chrome — có nghĩa là có gì đó trên đường mạng của bạn (một proxy doanh nghiệp, một thiết bị bảo mật, hoặc một công cụ kiểm tra) đang viết lại lần bắt tay của bạn.
Máy chủ sử dụng dấu vân tay TLS như thế nào
Phát hiện bot và tự động hóa
Ứng dụng phổ biến nhất là bắt các công cụ tự động hóa tự nhận là trình duyệt. Thư viện requests của Python, net/http của Go, curl và Scrapy đều có TLS handshake đặc trưng riêng. Khi một yêu cầu đến với header User-Agent: Mozilla/5.0 (Chrome ...) nhưng có giá trị băm JA3 khớp với OpenSSL binding của Python, sự không khớp đó là bằng chứng ngay lập tức của việc giả mạo.
Đây là đối ứng ở tầng mạng của kiểm tra sự không nhất quán dấu vân tay được mô tả trong hướng dẫn các kỹ thuật phát hiện bot. Nguyên tắc giống hệt: nếu hai tầng quan sát mâu thuẫn nhau, một trong số đó đang nói dối. TLS fingerprinting có một lợi thế cụ thể so với các kiểm tra dựa trên JavaScript — nó chạy trên luồng TCP thô trước khi trang tải, khiến nó vô hình với bot. Các máy chủ cũng kiểm tra dấu vân tay kết nối HTTP/2 — giá trị SETTINGS, mức tăng cửa sổ kiểm soát luồng và thứ tự pseudo-header — thêm chiều thứ hai ở tầng mạng: bot mô phỏng thành công TLS handshake của Chrome vẫn có thể bị phát hiện bởi các khung HTTP/2 mà thư viện của nó gửi trước yêu cầu đầu tiên.
Phát hiện VPN và proxy
Một VPN dạng tunnel thông thường (WireGuard, OpenVPN, IPSec) không thay đổi dấu vân tay TLS của bạn: trình duyệt của bạn vẫn thực hiện kết nối TLS riêng của mình, và VPN chỉ đơn giản là bọc lưu lượng đó ở tầng IP, vì vậy máy chủ đích thấy ClientHello thực sự của trình duyệt bạn. Điều mà TLS fingerprinting thực sự bắt được là sự chặn bắt. Proxy HTTPS inspection — và các ứng dụng VPN kết thúc TLS thay bạn — sử dụng thư viện TLS riêng của họ, tạo ra các handshake khác với bất kỳ trình duyệt thông thường nào. Ví dụ, một proxy HTTPS doanh nghiệp mã hóa lại lưu lượng và trình bày một ClientHello mới thường khớp với một sản phẩm bảo mật doanh nghiệp hơn là một trình duyệt. Các hệ thống phát hiện có thể gắn cờ điều này như bằng chứng cho thấy kết nối đang bị chặn bắt. Xem cách các website phát hiện VPN và proxy để có bức tranh đầy đủ về những gì khác được kiểm tra cùng với dấu vân tay TLS, bao gồm danh tiếng IP, sự không khớp địa lý và rò rỉ WebRTC.
Giám sát bảo mật
Ở phía phòng thủ, TLS fingerprinting giúp phát hiện phần mềm độc hại giao tiếp với máy chủ điều khiển và lệnh. Hầu hết phần mềm độc hại sẵn có và các framework khai thác đều sử dụng thư viện phổ biến (Python, Go, .NET) tạo ra JA3 nhận biết được, ngay cả khi tên miền hoặc địa chỉ IP thay đổi theo từng chiến dịch. Các hệ thống phát hiện xâm nhập mạng ghi lại giá trị băm JA3/JA4 và cảnh báo khi một chữ ký độc hại đã biết xuất hiện trên mạng.
Kiểm tra dấu vân tay TLS của chính bạn
So sánh dấu vân tay trực tiếp ở trên với trình duyệt mà bạn tin là mình đang chạy. Công cụ phát hiện bot của BrowserInsight phơi bày phần đối ứng bên trong trình duyệt — các dấu hiệu tự động hóa và rò rỉ trình duyệt headless — trong khi các giá trị JA3/JA4 ở tầng mạng đòi hỏi kiểm tra phía máy chủ như được trình bày ở trên, vì chúng được tính từ dữ liệu mà trình duyệt của bạn gửi trước khi bất kỳ JavaScript nào chạy.
Giảm thiểu: Thay đổi dấu vân tay TLS của bạn
Không giống dấu vân tay trình duyệt — mà bạn có thể giảm một phần bằng cách đổi trình duyệt hoặc bật chế độ riêng tư — thay đổi dấu vân tay TLS đòi hỏi phải thay đổi chính thư viện TLS, vì dấu vân tay được tạo ra bởi thư viện trước khi bất kỳ đoạn code của người dùng nào chạy.
Sử dụng trực tiếp trình duyệt mục tiêu. Cách đơn giản và đáng tin cậy nhất. Dấu vân tay của Chrome là chữ ký được mong đợi rộng rãi nhất trên web, và việc sử dụng cài đặt Chrome chưa chỉnh sửa đảm bảo TLS handshake của bạn khớp với những gì máy chủ mong đợi từ User-Agent của bạn.
Sử dụng thư viện giả lập TLS. Các công cụ như curl-impersonate sắp xếp lại cipher suite và extension để khớp chính xác với handshake của trình duyệt mục tiêu. Chúng được sử dụng chủ yếu bởi những người vận hành thu thập dữ liệu cần vượt qua các kiểm tra tầng TLS.
Sử dụng proxy dân cư kết thúc bằng trình duyệt thật. Một số dịch vụ proxy chuyển tiếp yêu cầu qua một đường ống được hỗ trợ bởi một engine trình duyệt thực sự, bảo toàn dấu vân tay TLS của trình duyệt từ đầu đến cuối.
Đối với hầu hết người dùng thông thường, TLS fingerprinting là vô hình và không cần thực hiện bất kỳ hành động nào. Nó trở nên liên quan khi bạn vận hành tự động hóa cần mạo danh một trình duyệt thực, hoặc khi bạn muốn hiểu tại sao một thiết bị mạng hay CDN đang gắn cờ lưu lượng của bạn.
Câu hỏi thường gặp
TLS 1.3 có khiến việc lấy dấu vân tay khó hơn không?
Có phần nào. TLS 1.3 mã hóa nhiều hơn TLS 1.2 trong quá trình bắt tay, bao gồm cả chứng chỉ của máy chủ — nhưng chính ClientHello vẫn nhất thiết phải ở dạng văn bản thường, vì máy chủ phải đọc nó trước khi các khóa chung tồn tại. ClientHello vẫn chứa đủ biến thể để lấy dấu vân tay client một cách đặc trưng, và JA4 được thiết kế đặc biệt với TLS 1.3 trong tâm trí. Một extension mới nổi thực sự thay đổi bức tranh: Encrypted Client Hello (ECH) mã hóa ClientHello nội bộ nhạy cảm bằng khóa mà máy chủ công bố trong DNS. Nơi ECH được triển khai (Chrome và Cloudflare đã hỗ trợ nó từ 2023–2024), người quan sát mạng chỉ thấy một ClientHello bên ngoài tối thiểu, điều này giới hạn những gì có thể bị lấy dấu vân tay.
TLS fingerprinting có hợp pháp không?
Có, trong các bối cảnh thông thường. Các máy chủ luôn được phép đọc lưu lượng được gửi đến chúng, và ClientHello là phần của sự trao đổi phải ở dạng văn bản thường theo thiết kế của giao thức. Sử dụng dữ liệu đó để phân loại client không khác gì phân tích các header HTTP.
Proxy HTTPS inspection có thể ẩn dấu vân tay ban đầu không?
Không — nó thay thế bằng một dấu vân tay khác. Một proxy giải mã và mã hóa lại lưu lượng HTTPS trình bày ClientHello của riêng mình, thường khớp với thư viện TLS của phần mềm proxy hơn là trình duyệt của người dùng. Các hệ thống phát hiện kiểm tra dấu vân tay mong đợi sẽ thấy chữ ký proxy thay thế, điều đó tự nó thường là một cờ hiệu.
GREASE là gì và tại sao nó ảnh hưởng đến JA3?
GREASE (Generate Random Extensions And Sustain Extensibility) là một cơ chế được định nghĩa trong RFC 8701 nơi các triển khai TLS quảng bá các giá trị giả dự trữ — được rút từ tập hợp cố định các điểm code GREASE — trong ClientHello của chúng. Mục tiêu là đảm bảo rằng các máy chủ và thiết bị trung gian không từ chối kết nối chỉ vì chúng chứa một trường không nhận ra — giữ cho giao thức có thể mở rộng. Vì JA3 bao gồm các giá trị GREASE này theo nghĩa đen, một bản cập nhật Chrome thay đổi lựa chọn GREASE của nó sẽ làm thay đổi giá trị băm JA3 ngay cả khi không có gì thay đổi về chức năng. JA4 giải quyết điều này bằng cách xóa các giá trị GREASE trước khi băm.


