การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป
นำ HPKP และการตรึงใบรับรองในรูปแบบ TrustKit ไปใช้ พร้อมทำความเข้าใจความเสี่ยงด้านการปฏิบัติการของการตรึงใบรับรอง
การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป เป็นบทเรียน Cryptology Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Cryptology Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Cryptology Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่มีการตรึงใบรับรอง
TLS มาตรฐานเชื่อถือใบรับรองใด ๆ ที่ลงนามโดย CA รากใด ๆ จากประมาณ 150 รายการที่ติดตั้งไว้ล่วงหน้าใน OS หาก CA รากรายการใดถูกเจาะหรือถูกบีบบังคับ ผู้โจมตีสามารถขอใบรับรองสำหรับโดเมนใดก็ได้และดักจับทราฟฟิก TLS การตรึงใบรับรองจะจำกัดความเชื่อถือไว้ที่ใบรับรองหรือคีย์สาธารณะรายการใดรายการหนึ่ง โดยไม่ขึ้นกับว่า CA ใดเป็นผู้ลงนาม แอปพลิเคชันที่ใช้การตรึงจะปฏิเสธการเชื่อมต่อไปยังเซิร์ฟเวอร์ เว้นแต่เซิร์ฟเวอร์จะแสดงใบรับรองหรือคีย์ที่ตรงกับรายการที่คาดหมายทุกประการ การป้องกันนี้มีคุณค่าเป็นพิเศษสำหรับแอปพลิเคชันมือถือ ซึ่งผู้ใช้ไม่สามารถตรวจสอบทราฟฟิกเครือข่ายได้ และโซลูชัน MDM ขององค์กรอาจติดตั้ง CA รากขององค์กร
ประเภทการตรึง: ใบรับรองกับคีย์สาธารณะกับ SPKI
การตรึงมีสามระดับความละเอียด ได้แก่ (1) การตรึงใบรับรองทั้งฉบับ — ใบรับรองที่เข้ารหัสด้วย DER ทุกไบต์ต้องตรงกัน วิธีนี้เปราะบางที่สุด เพราะจะล้มเหลวเมื่อมีการต่ออายุใบรับรองทุกครั้ง (2) การตรึงคีย์สาธารณะ — เปรียบเทียบเฉพาะไบต์ของ SubjectPublicKeyInfo (SPKI) เท่านั้น การต่ออายุใบรับรองยังทำได้หากยังใช้คู่คีย์เดิม (3) แฮชของ SPKI — จัดเก็บ SHA-256(SPKI) แทนคีย์ดิบ นี่คือแนวทางของการตรึงคีย์สาธารณะผ่าน HTTP (HPKP) และ Android Network Security Config โดยทั่วไปควรใช้การตรึงคีย์สาธารณะหรือ SPKI เพราะรองรับการเปลี่ยน CA และการต่ออายุใบรับรอง ขณะเดียวกันยังตรวจจับ MITM ที่ใช้คู่คีย์อื่นได้
การกำหนดค่าความปลอดภัยเครือข่ายของ Android
Android (API 24 ขึ้นไป) มีกลไกการตรึงแบบประกาศผ่าน XML ของ Network Security Config ไฟล์ res/xml/network_security_config.xml ระบุการตรึงแยกตามโดเมน โดยใช้ pin-set ที่มี digest="SHA-256" และแฮช SPKI ที่เข้ารหัสแบบ base64 แอปพลิเคชันอ้างอิงไฟล์นี้ใน AndroidManifest.xml ผ่าน android:networkSecurityConfig Android จะบังคับใช้การตรึงกับการเชื่อมต่อ HTTP ทั้งหมดที่สร้างผ่าน HttpsURLConnection มาตรฐานและ OkHttp (เมื่อใช้ตัวจัดการความเชื่อถือของแพลตฟอร์ม) pin-set ต้องมีการตรึงสำรองอย่างน้อยหนึ่งรายการ (คีย์อื่นหรือการตรึง CA) เพื่อป้องกันการถูกล็อกออกหากคีย์หลักถูกเจาะ การหมดอายุของการตรึง (แอตทริบิวต์ expiration) บังคับให้แอปพลิเคชันอัปเดตก่อนที่การตรึงจะล้าสมัย
การตรึงใบรับรองบน iOS / macOS
แอปพลิเคชัน iOS ใช้ผู้รับมอบหมายของ NSURLSession เพื่อทำการตรึง เมธอดผู้รับมอบหมาย URLSession(_:didReceive:completionHandler:) จะได้รับออบเจ็กต์ความเชื่อถือของเซิร์ฟเวอร์ แอปพลิเคชันเรียก SecTrustEvaluateWithError เพื่อตรวจสอบสายใบรับรอง จากนั้นดึงใบรับรองปลายทางด้วย SecTrustGetCertificateAtIndex(trust, 0) ส่งออกไบต์ SPKI คำนวณแฮชด้วย SHA-256 และเปรียบเทียบกับการตรึงที่จัดเก็บไว้ TrustKit (ไลบรารีโอเพนซอร์ส) ครอบรูปแบบนี้ด้วยการตรึงตามการกำหนดค่า โดยรองรับการตรึงหลายรายการ การจับคู่โดเมนย่อย และโหมดรายงานเท่านั้น App Transport Security (ATS) ของ Apple แยกจากการตรึง โดย ATS บังคับใช้เวอร์ชัน TLS ขั้นต่ำ แต่ไม่ได้ตรึงคีย์
HPKP: การตรึงคีย์สาธารณะผ่าน HTTP (เลิกใช้แล้ว)
การตรึงคีย์สาธารณะผ่าน HTTP (HPKP, RFC 7469) พยายามเพิ่มการตรึงให้เว็บเบราว์เซอร์ผ่านส่วนหัวการตอบกลับ HTTP: Public-Key-Pins: pin-sha256="base64=="; max-age=5184000; includeSubDomains เบราว์เซอร์จะจดจำการตรึงเป็นระยะเวลาตาม max-age และปฏิเสธการเชื่อมต่อกับคีย์ที่ไม่ตรงกัน Chrome เลิกใช้ HPKP ในปี 2017 และนำออกในปี 2019 เนื่องจากความล้มเหลวร้ายแรง การกำหนดค่าผิดพลาดหรือการสูญเสียคีย์เพียงครั้งเดียวอาจทำให้ผู้ใช้ถูกล็อกออกจากเว็บไซต์อย่างถาวรโดยไม่มีช่องทางกู้คืน ปัจจุบัน HPKP แทบไม่มีการใช้งานในเว็บเบราว์เซอร์แล้ว แต่การตรึงระดับแอปพลิเคชันในแอปพลิเคชันมือถือยังใช้ได้ เพราะสามารถส่งการตรึงใหม่ไปพร้อมกับการอัปเดตแอปพลิเคชัน
การตรึงใน OkHttp
OkHttp (ซึ่งใช้อย่างแพร่หลายบน Android) รองรับการตรึงผ่าน CertificatePinner: CertificatePinner.Builder().add("api.example.com", "sha256/AAAA...==", "sha256/BBBB...==").build(). การตรึงรายการที่สองคือการตรึงสำรอง OkHttp ตรวจสอบว่ามีการตรึงอย่างน้อยหนึ่งรายการตรงกับใบรับรองใด ๆ ในสายใบรับรองของเซิร์ฟเวอร์ ไม่ว่าจะเป็นใบรับรองปลายทาง ใบรับรองขั้นกลาง หรือใบรับรองราก วิธีนี้ทำให้ตรึงกับ CA ขั้นกลางได้ (รองรับการหมุนเวียนใบรับรองปลายทาง) หรือตรึงกับ CA รากได้ (รองรับการหมุนเวียน CA ขั้นกลาง) OkHttp จะแจ้งข้อยกเว้น SSLPeerUnverifiedException พร้อมข้อความที่เป็นประโยชน์ซึ่งแสดงแฮช SPKI จริงของเซิร์ฟเวอร์ ทำให้การดึงการตรึงระหว่างการพัฒนาเป็นเรื่องง่าย
การข้ามการตรึง: เทคนิคของผู้โจมตี
การตรึงยกระดับความยากในการดักจับทราฟฟิก แต่ไม่สามารถทำลายไม่ได้ เทคนิคการข้ามที่พบบ่อยบนอุปกรณ์มือถือ ได้แก่ (1) การดักฮุกด้วย Frida — แทรก JavaScript เข้าไปในโพรเซสของแอปพลิเคชันเพื่อดักเมธอดตรวจสอบการตรึงและให้คืนค่า true เสมอ (2) เครื่องมือ SSLUnpinning — สคริปต์ Frida/Objection อัตโนมัติที่มุ่งเป้าไปยังไลบรารีการตรึงที่ใช้กันทั่วไป เช่น TrustKit, OkHttp และ SecTrust แบบเนทีฟ (3) ROM แบบกำหนดเอง — ได้สิทธิ์ root บนอุปกรณ์และแก้ไขสแตก TLS (4) การบรรจุแพ็กเกจใหม่ — แยกส่วน APK แก้ไขการกำหนดค่าการตรึง แล้วบรรจุแพ็กเกจใหม่ด้วยใบรับรองใหม่ (5) การแพตช์หน่วยความจำ — แก้ไขไบต์โค้ดตรวจสอบขณะทำงาน มาตรการลดความเสี่ยง ได้แก่ การตรวจจับ root หรือ jailbreak การทำให้โค้ดอ่านได้ยาก และการตรวจสอบความสมบูรณ์ (SafetyNet/App Attest)
การตรึงสำรองและการกู้คืนจากภัยพิบัติ
ความเสี่ยงด้านปฏิบัติการที่ใหญ่ที่สุดของการตรึงใบรับรองคือการล็อกตัวเองออก หากคีย์สำหรับระบบจริงสูญหายหรือใบรับรองหมดอายุและไม่สามารถใช้คีย์สำรองได้ ผู้ใช้จะถูกล็อกออกจนกว่าจะมีการส่งอัปเดตแอปพลิเคชัน ซึ่งอาจใช้เวลาหลายวันถึงหลายสัปดาห์ แนวทางปฏิบัติที่ดี ได้แก่ (1) ตรึงคีย์อย่างน้อยสองรายการเสมอ ได้แก่ คีย์ปัจจุบันและคีย์สำรองที่สร้างไว้ล่วงหน้าและจัดเก็บแบบออฟไลน์ (ใน HSM หรือระบบแยกขาดจากเครือข่าย) (2) กำหนดวันหมดอายุของการตรึงและส่งอัปเดตแอปพลิเคชันก่อนถึงวันดังกล่าว (3) ตรวจสอบความล้มเหลวของการตรึงด้วยโหมดรายงานเท่านั้นก่อนบังคับใช้ (4) จัดเตรียมกระบวนการส่งอัปเดตแอปพลิเคชันฉุกเฉิน (การตรวจสอบแบบเร่งด่วน) สำหรับเหตุการณ์หมุนเวียนการตรึง (5) ตรึงที่ระดับ CA ขั้นกลาง ไม่ใช่ใบรับรองปลายทาง เพื่อให้หมุนเวียนใบรับรองปลายทางได้โดยไม่ต้องอัปเดตแอปพลิเคชัน
การตรึงในแอปพลิเคชันเดสก์ท็อป
แอปพลิเคชันเดสก์ท็อปที่เขียนด้วย Electron, Qt หรือโค้ดเนทีฟสามารถใช้การตรึงผ่านส่วนติดต่อของสแตก TLS ได้ แอปพลิเคชัน Electron ใช้เหตุการณ์ app.on("certificate-error") และ session.setCertificateVerifyProc() เพื่อทำการตรวจสอบแบบกำหนดเอง โค้ดเครือข่ายของ Qt ใช้ QSslSocket พร้อมฟังก์ชันเรียกกลับสำหรับการตรวจสอบแบบกำหนดเอง แอปพลิเคชัน .NET ใช้ ServicePointManager.ServerCertificateValidationCallback แอปพลิเคชัน Windows แบบเนทีฟใช้ WinHTTP พร้อมตรวจสอบใบรับรองด้วยตนเอง แอปพลิเคชันเดสก์ท็อปมีความท้าทายเพิ่มเติม ได้แก่ การดักตรวจสอบ TLS ระดับ OS ผ่านพร็อกซีขององค์กรมักเกิดขึ้น และผู้ใช้อาจคาดหวังให้ฟังก์ชันพร็อกซีทำงานได้ตามปกติ จึงต้องตัดสินใจเชิงนโยบายว่าการตรึงจะมีผลเฉพาะกับปลายทางบางรายการหรือไม่
การตรึงใน CI/CD และการทดสอบอัตโนมัติ
การตรึงใบรับรองทำให้การทดสอบอัตโนมัติและกระบวนการ CI/CD ซับซ้อนขึ้น การทดสอบแบบผสานรวมที่เรียก HTTPS จริงไปยังเซิร์ฟเวอร์สำหรับการทดสอบต้องใช้ใบรับรองทดสอบที่มีแฮช SPKI ถูกตรึงไว้ในการกำหนดค่าสำหรับการทดสอบ แนวทางต่าง ๆ ได้แก่ (1) รูปแบบการสร้าง — รุ่นแก้ไขข้อบกพร่องหรือทดสอบมีการตรึงของเซิร์ฟเวอร์ทดสอบ ส่วนรุ่นเผยแพร่มีการตรึงของระบบจริง (2) การแทนที่ Network Security Config — Android อนุญาตให้กำหนดค่าการตรึงเฉพาะสำหรับการแก้ไขข้อบกพร่อง (3) เซิร์ฟเวอร์จำลอง — ดักที่ชั้นไคลเอนต์ HTTP ก่อน TLS เพื่อข้ามการตรึงทั้งหมด (4) CA ที่ลงนามเองสำหรับ CI — ออกใบรับรองทดสอบจาก CA ของ CI ซึ่งรากของ CA นี้ได้รับความเชื่อถือเฉพาะในรุ่นสำหรับการทดสอบเท่านั้น ห้ามส่งรุ่นที่ปิดการตรึงไปใช้งานจริงโดยเด็ดขาด
ข้อพิจารณาด้านยุคหลังควอนตัมสำหรับการตรึง
การตรึงใบรับรองมักเป็นแฮชของคีย์สาธารณะ RSA หรือ EC เมื่อเริ่มการย้ายไปสู่ยุคหลังควอนตัม เซิร์ฟเวอร์จะเปลี่ยนไปใช้ ML-DSA (CRYSTALS-Dilithium) หรือคีย์แบบผสม แฮช SPKI ที่ตรึงไว้จะเปลี่ยนไป เพราะประเภทและการเข้ารหัสของคีย์เปลี่ยนแปลง แอปพลิเคชันที่ตรึงใบรับรองปลายทางหรือคีย์สาธารณะจะต้องอัปเดตให้ประสานกัน ได้แก่ (1) ส่งแอปพลิเคชันรุ่นใหม่ที่มีแฮช SPKI หลังควอนตัมเป็นการตรึงสำรองก่อนการย้ายเซิร์ฟเวอร์ (2) ดำเนินการย้ายเซิร์ฟเวอร์ให้เสร็จสิ้น (3) ส่งการอัปเดตเพื่อนำการตรึงแบบดั้งเดิมรายการเก่าออก ช่วงเปลี่ยนผ่านนี้ต้องอาศัยการประสานงานอย่างรอบคอบ แอปพลิเคชันที่ตรึง CA ขั้นกลางหรือ CA รากจะได้รับผลกระทบน้อยกว่า เพราะมีเพียงคีย์ของ CA ที่เปลี่ยน และไม่จำเป็นต้องเปลี่ยนตามกำหนดเวลาเดียวกับใบรับรองปลายทาง
แบบทดสอบการตรึงใบรับรอง
เหตุใดจึงนิยมตรึงแฮชของ SubjectPublicKeyInfo (SPKI) มากกว่าตรึงใบรับรองทั้งฉบับ
ทบทวนการตรึงใบรับรอง
การตรึงใบรับรองจะจำกัดความเชื่อถือของ TLS ไว้ที่ใบรับรองหรือกุญแจสาธารณะที่ระบุ จึงช่วยป้องกันการที่ CA ถูกเจาะและการโจมตีแบบ MITM การตรึงแฮช SPKI (SHA-256 ของ SubjectPublicKeyInfo) เป็นที่นิยมกว่าการตรึงใบรับรองทั้งฉบับ เพราะรองรับการต่ออายุได้ยืดหยุ่นกว่า Android ใช้ Network Security Config XML ส่วน iOS ใช้ตัวแทนของ URLSession ร่วมกับอินเทอร์เฟซของ SecTrust และ OkHttp รองรับ CertificatePinner ควรใส่ค่าตรึงสำรองไว้เสมอ เพื่อป้องกันไม่ให้แอปล็อกตัวเองจนเข้าใช้งานไม่ได้ HPKP (ส่วนหัว HTTP ของเบราว์เซอร์) เลิกใช้งานแล้ว การตรึงใบรับรองอาจถูกหลีกเลี่ยงได้ด้วยฮุกของ Frida และการดัดแปลง ROM การย้ายไปใช้กุญแจหลังยุคควอนตัมจำเป็นต้องอัปเดตแอปแบบประสานกัน เพื่ออัปเดตค่าแฮช SPKI
คำถามที่พบบ่อย
บทเรียน “การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Cryptology Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Cryptology Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป”
นำ HPKP และการตรึงใบรับรองในรูปแบบ TrustKit ไปใช้ พร้อมทำความเข้าใจความเสี่ยงด้านการปฏิบัติการของการตรึงใบรับรอง คุณปฏิบัติ Cryptology Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Cryptology Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Cryptology Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Cryptology Academy นี้ได้ไหม
ได้ บทเรียน Cryptology Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- TLS 1.3: 0-RTT ข้อมูลล่วงหน้า และการกลับมาใช้เซสชันต่อ
- รูปแบบการนำ Mutual TLS (mTLS) ไปใช้งาน
- การตรึงใบรับรองในแอปพลิเคชันมือถือและเดสก์ท็อป
- ประสิทธิภาพ TLS: QUIC และ HTTP/3