สแครปเปอร์ของคุณส่ง header ของ Chrome ที่สมบูรณ์แบบ ทำงานอยู่หลัง IP residential ที่สะอาด แต่ก็ยังโดน 403 ตั้งแต่ request แรกเลย ไม่มี captcha ไม่มีหน้า challenge ไม่มีอะไรให้แก้ เว็บไซต์ระบุตัวคุณได้ ก่อนที่จะมีการแลกเปลี่ยน HTTP แม้แต่ไบต์เดียว — ในระหว่างการทำ TLS handshake
บทความนี้อธิบายว่า JA3 และ JA4 fingerprinting ทำงานอย่างไรจริง ๆ ทำไมมันถึงเป็นกำลังหลักเงียบ ๆ ของระบบ anti-bot รายใหญ่ทุกระบบในปี 2026 และคุณจะดู fingerprint ของตัวเองได้อย่างไรภายในสิบวินาที ถ้าคุณอยากได้เครื่องมือ bypass ก่อน เราได้ครอบคลุมไว้แล้วใน Bypass TLS Fingerprinting with curl_cffi & tls-client — บทความนี้คือคู่หูที่ว่าด้วยฝั่งของการตรวจจับว่าทำงานอย่างไร
ก่อนเข้าทฤษฎี ลองดู handshake ของตัวคุณเอง เปิดเครื่องมือตรวจ JA3/JA4 ฟรีของเรา — มันจะสะท้อน TLS fingerprint ที่ client ของคุณเพิ่งนำเสนอกลับมา และบอกคุณว่ามันตรงกับอะไร:
# From a terminal - see what curl's TLS looks like:
curl https://www.jibaoproxy.com/tools/fingerprint.html
# Then open the same URL in Chrome and compare.
รันทั้งสองอย่างแล้วคุณจะเห็นประเด็นของบทความทั้งหมดนี้: curl และ Chrome สร้าง fingerprint ที่แตกต่างกันโดยสิ้นเชิง ไม่ว่าคุณจะตั้ง header User-Agent เป็นอะไรก็ตาม
การเชื่อมต่อ HTTPS ทุกครั้งเริ่มต้นด้วยข้อความ ClientHello ซึ่งส่งเป็น cleartext ก่อนที่การเข้ารหัสใด ๆ จะเริ่มขึ้น ในข้อความนั้น client ของคุณจะประกาศ:
นี่คือข้อมูลเชิงลึกของการตรวจจับ: รายการเหล่านี้และลำดับที่แน่นอนของมันถูกฝังอยู่ในไลบรารี TLS ที่ client ของคุณถูกคอมไพล์ขึ้นมา BoringSSL ของ Chrome ประกาศชุดเฉพาะหนึ่งชุด OpenSSL ของ Python ประกาศอีกชุดที่แตกต่างออกไป crypto/tls ของ Go ก็เป็นชุดที่สาม คุณไม่สามารถเปลี่ยนสิ่งนี้ด้วย header ได้ — มันถูกเจรจาต่อรองที่ระดับต่ำกว่าชั้น HTTP โดยตัวไลบรารีเอง
JA3 (Salesforce, 2017) เชื่อมต่อห้าฟิลด์ของ ClientHello เข้าด้วยกัน — เวอร์ชัน TLS, ciphers, extensions, curves, point formats — เป็นสตริงหนึ่งแล้วทำ MD5-hash:
771,4865-4866-4867-49195-49199,0-23-65281-10-11-35-16,29-23-24,0
|
v MD5
cd08e31494f9531f560d64c695473da9
หนึ่ง hash ต่อหนึ่ง TLS stack Chrome 137 ทุกชุดบน Windows สร้าง JA3 ที่ (เกือบ) เหมือนกัน python-requests ทุกตัวบน OpenSSL 3.x สร้าง JA3 ที่แตกต่างออกไปแบบเดียวกัน ฝ่ายป้องกันจะดูแลตารางค้นหา: hash X = Chrome, hash Y = requests, hash Z = Go bot ถ้า User-Agent ของคุณบอกว่าเป็น Chrome แต่ JA3 ของคุณบอกว่าเป็น OpenSSL คุณจะถูกบล็อก — ทันที เงียบ ๆ และต้นทุนต่ำ
JA3 มีปัญหา: Chrome เริ่มสุ่มลำดับ extension ในปี 2023 (ทำให้ JA3 แบบง่าย ๆ พัง) และ MD5 ไม่มีโครงสร้าง — hash หนึ่งไม่บอกอะไรคุณเลยว่าทำไม client สองตัวถึงต่างกัน JA4 (FoxIO, 2023) แก้ทั้งสองอย่างและเป็นสิ่งที่ผู้ให้บริการจริงจังใช้กันในปัจจุบัน:
JA4 = t13d1516h2_8daaf6152771_b0da82dd1658
| | |
a: protocol b: ciphers c: extensions
(TLS 1.3, 16 ciphers, (sorted, truncated
h2 ALPN, domain SNI) SHA256)
ทุกระบบที่สำคัญ: Cloudflare เปิดเผย JA3/JA4 โดยตรงในกฎ bot-management ของมัน DataDome และ PerimeterX ป้อนมันเข้าสู่การให้คะแนนระดับเครือข่ายของพวกเขา (ดู คู่มือ DataDome/PerimeterX ของเรา) Akamai ใช้ TLS fingerprinting มานานที่สุดในบรรดาทั้งหมด มันได้รับความนิยมเพราะ คำนวณได้ฟรี ปลอมจากชั้น HTTP ไม่ได้ และจับ automation แบบง่าย ๆ ได้ 90% — ทุกสคริปต์ requests/httpx/axios/Go-http ที่เคยเขียนมา — ก่อนที่ JavaScript ใด ๆ จะต้องรัน
เรื่องนี้ทำให้คนประหลาดใจ: proxy เปลี่ยน IP ของคุณ แต่ TLS handshake ของคุณผ่านไปโดยไม่เปลี่ยนแปลง CONNECT tunnel (หรือ SOCKS5 stream) นำไบต์ ClientHello ของคุณไปยังเป้าหมายแบบเป๊ะ ๆ IP residential + JA3 ของไลบรารี requests = "bot ที่ทำงานอยู่บน IP residential" ดีกว่า IP ของ datacenter แต่ก็ยังเป็น bot อยู่ดี
IP และ TLS fingerprint เป็นสัญญาณที่เป็นอิสระต่อกัน และคุณต้องสะอาดทั้งสองอย่าง:
| IP | TLS fingerprint | คำตัดสินในปี 2026 |
|---|---|---|
| Datacenter | Library (requests/Go) | ถูกบล็อกทุกที่ที่ใส่ใจ |
| Residential | Library | ถูกบล็อกบนเว็บไซต์ที่ตรวจ JA4 |
| Datacenter | Browser-impersonated | ถูกบล็อกจากชื่อเสียงของ IP |
| Residential | Browser-impersonated | ผ่านการตรวจสอบระดับเครือข่าย |
มีสองเส้นทาง ตามเครื่องมือ:
HTTP clients — ใช้ไลบรารี impersonation ที่ implement ClientHello ที่แม่นยำของเบราว์เซอร์ขึ้นมาใหม่: curl_cffi (Python), tls-client (Python/Go), got-scraping (Node) โค้ดที่ใช้งานได้เต็มรูปแบบอยู่ใน คู่มือ curl_cffi:
from curl_cffi import requests
r = requests.get(
"https://target.example",
impersonate="chrome",
proxies={"https": "socks5h://USERNAME:[email protected]:913"},
)
เบราว์เซอร์จริง (Playwright, browser agents, anti-detect browsers) — ไม่ต้องทำอะไรที่ชั้น TLS เลย fingerprint เป็นของ Chrome จริง ๆ ความเสี่ยงของคุณอยู่ที่อื่น: ชื่อเสียงของ IP และการตรวจจับ CDP
จากนั้นจง ตรวจสอบ อย่าสันนิษฐาน เวอร์ชันมีการเปลี่ยนแปลงเรื่อยมา — ไลบรารี impersonation ที่ตรึงไว้กับ handshake ของ Chrome 120 จะถูกอ่านว่าเป็น "เบราว์เซอร์เก่าน่าสงสัย" ในปี 2026 ทดสอบใหม่หลังการอัปเดต dependency ทุกครั้ง:
จับคู่ TLS ที่ impersonate แล้วของคุณกับ IP residential — 500MB ทราฟฟิกฟรี ไม่ต้องใช้บัตร
เริ่มทดลองใช้ฟรีผู้ใช้ใหม่รับ 500MB เมื่อสมัครสมาชิก พร้อมโบนัสในการเติมเงินครั้งแรก ข้อเสนอมีระยะเวลาจำกัด