Certificate Pinning เป็นกลไกการยึดใบรับรองหรือคีย์สาธารณะของเซิร์ฟเวอร์ ซึ่งแอปพลิเคชันใช้ลายนิ้วมือที่ทราบล่วงหน้าเพื่อตรวจสอบการเชื่อมต่อ HTTPS แตกต่างจากห่วงโซ่ความเชื่อถือมาตรฐานผ่าน CA การปักหมุดรับประกันว่าแม้หน่วยงานออกใบรับรองที่ถูกบุกรุกก็ไม่สามารถออกใบรับรองปลอมสำหรับโดเมนของคุณได้ ตาม OWASP MSTG (2025) Certificate Pinning อยู่ในรายการการควบคุมบังคับสำหรับแอปพลิเคชันระดับการป้องกัน L2 การนำไปใช้รวมถึงการเก็บแฮชของใบรับรองในโค้ดและการตรวจสอบในทุกคำขอ
ประเด็นสำคัญ
Certificate Pinning เป็นเทคนิคความปลอดภัยที่แอปพลิเคชันเก็บลายนิ้วมือของใบรับรองที่เชื่อถือได้และใช้เป็นเกณฑ์เดียวในการสร้างการเชื่อมต่อ HTTPS ในโมเดล TLS มาตรฐาน ไคลเอนต์ตรวจสอบว่าใบรับรองของเซิร์ฟเวอร์ลงนามโดย CA รูทที่เชื่อถือได้ — หนึ่งในหลายร้อยหน่วยงานออกใบรับรองที่ติดตั้งไว้ล่วงหน้าในระบบ Certificate Pinning แทนที่ห่วงโซ่นี้ด้วยการตรวจสอบโดยตรง: ใบรับรองต้องตรงกับตัวอย่างที่เก็บไว้หรือมีคีย์สาธารณะที่คาดไว้
ปัญหาของโมเดลมาตรฐานปรากฏชัดเจนหลังจากเหตุการณ์การบุกรุก CA — DigiNotar (2011), Comodo (2011), TrustCor (2022) หาก CA ออกใบรับรองปลอมสำหรับโดเมนของคุณ เบราว์เซอร์หรือแอปพลิเคชันจะยอมรับว่าใช้ได้ Certificate Pinning ป้องกันการโจมตีนี้: แม้แต่ใบรับรองปลอมที่ลงนามอย่างสมบูรณ์จะถูกปฏิเสธเพราะลายนิ้วมือของมันไม่ตรงกับที่ปักหมุดในแอปพลิเคชัน
คำว่า pinning มาจาก pin — «หมุด» หรือ «ตัวยึด»: นักพัฒนายึดใบรับรองที่เชื่อถือได้ และการเบี่ยงเบนใด ๆ จากนั้นจะบล็อกการเชื่อมต่อ จากการวิจัยของ Mitre CWE-295 การตรวจสอบใบรับรองที่ไม่เหมาะสมยังคงเป็นหนึ่งใน 10 ข้อผิดพลาดด้านความปลอดภัยที่อันตรายที่สุดในแอปพลิเคชันมือถือ และ Certificate Pinning เป็นวิธีการโดยตรงในการป้องกัน
เดิมที Certificate Pinning ถูกใช้ในเบราว์เซอร์ผ่านกลไก HPKP (HTTP Public Key Pinning) ซึ่งกำหนดมาตรฐานใน RFC 7469 นักพัฒนาส่งหัวข้อ HTTP Public-Key-Pins พร้อมแฮชของคีย์ที่คาดหวัง และเบราว์เซอร์จะเก็บไว้ตามระยะเวลาที่กำหนด อย่างไรก็ตาม HPKP กลับกลายเป็นอันตราย: ข้อผิดพลาดในการกำหนดค่าเพียงครั้งเดียวสามารถบล็อกไซต์ได้เป็นเดือน ในปี 2018 Chrome ยุติการสนับสนุน HPKP และมาตรฐานปัจจุบันกลายเป็น การนำไปใช้ฝั่งไคลเอนต์ — ภายในแอปพลิเคชันมือถือหรือส่วนขยายเบราว์เซอร์
กระบวนการ Certificate Pinning ประกอบด้วยสามขั้นตอนสำคัญ: การคำนวณลายนิ้วมือ การตรวจสอบการเชื่อมต่อ และการจัดการข้อผิดพลาด ในขั้นตอนการเตรียมการ นักพัฒนาได้รับแฮช SHA-256 ของใบรับรองหรือคีย์สาธารณะของเซิร์ฟเวอร์ที่ใช้งานจริง สำหรับแอปพลิเคชันที่ปฏิบัติตาม GDPR และ PCI DSS ยังจำเป็นต้องยึดลายนิ้วมือของ CA ระดับกลาง ในห่วงโซ่ด้วย
ในทุกคำขอ HTTPS แอปพลิเคชันจะสกัดกั้นการเรียกกลับการรับรองความถูกต้อง TLS แยกใบรับรองของเซิร์ฟเวอร์และคำนวณแฮช SHA-256 แฮชนี้จะถูกเปรียบเทียบกับรายการลายนิ้วมือที่เชื่อถือได้ที่เก็บไว้ หากพบการตรงกัน — การเชื่อมต่อดำเนินต่อไป หากไม่ — แอปพลิเคชันต้อง ยุติการเชื่อมต่อ และรายงานข้อผิดพลาดโดยไม่เปิดเผยรายละเอียดการนำไปใช้แก่ผู้โจมตี
fun validateCertificate(certificate: X509Certificate,
expectedHash: String): Boolean {
val digest = MessageDigest.getInstance("SHA-256")
val hash = Base64.encodeToString(
digest.digest(certificate.publicKey.getEncoded()),
Base64.DEFAULT
).trim()
return hash == expectedHash
}
ฟังก์ชันรับวัตถุ X509Certificate จากเซิร์ฟเวอร์และแฮชที่คาดหวัง ขั้นแรกจะแยกคีย์สาธารณะของใบรับรอง คำนวณแฮช SHA-256 และเข้ารหัสเป็น Base64 ผลลัพธ์จะถูกเปรียบเทียบกับ ลายนิ้วมือที่คาดหวัง ในระบบจริง ควรเพิ่มการตรวจสอบกับอาร์เรย์ของลายนิ้วมือ 2–3 รายการเพื่อรองรับการหมุนเวียน
เมื่อนำ pinning ไปใช้ ต้องเลือกวัตถุเข้ารหัสที่จะยึด Certificate Pinning ผูกกับใบรับรอง X.509 เอง — หมายเลขซีเรียล ระยะเวลาที่มีผล และห่วงโซ่ทั้งหมด Public Key Pinning ยึดเฉพาะคีย์สาธารณะภายในใบรับรอง โดยไม่สนใจฟิลด์อื่น ๆ ตัวเลือกนี้มีผลกระทบอย่างมากต่อค่าใช้จ่ายในการดำเนินงาน
| เกณฑ์ | Certificate Pinning | Public Key Pinning |
|---|---|---|
| วัตถุที่ยึด | ใบรับรอง X.509 ทั้งหมด | คีย์สาธารณะ RSA/ECDSA |
| การหมุนเวียน | ต้องการอัปเดตทุกครั้งที่ออกใหม่ | ไม่เปลี่ยนแปลงเมื่อต่ออายุใบรับรองด้วยคีย์เดียวกัน |
| ความปลอดภัย | การผูกที่แม่นยำสูงสุด | ไวต่อรายละเอียดน้อยกว่า |
| ความยืดหยุ่น | ต่ำ — ใบรับรองเปลี่ยนทุก 1–2 ปี | สูง — คีย์สามารถใช้งานได้ 5–10 ปี |
| คำแนะนำ | สำหรับระบบวิกฤตที่มีการอัปเดตควบคุม | สำหรับแอปพลิเคชันมือถือและ API ส่วนใหญ่ |
Public Key Pinning เป็นตัวเลือกที่ต้องการสำหรับโครงการส่วนใหญ่ คีย์สาธารณะของเซิร์ฟเวอร์มักจะไม่เปลี่ยนแปลงเมื่อออกใบรับรองใหม่ — บริษัทเพียงแค่ลงนามคีย์เก่าด้วยใบรับรองใหม่ ซึ่งหมายความว่าแอปพลิเคชันไม่ต้องการอัปเดตหลังจากเปลี่ยนใบรับรองหากคู่คีย์ไม่เปลี่ยนแปลง ในทางกลับกัน Certificate Pinning แนะนำสำหรับสถานการณ์ที่นักพัฒนาควบคุมทั้งเซิร์ฟเวอร์และโค้ดไคลเอนต์อย่างสมบูรณ์ เช่น ในแอปพลิเคชันองค์กรที่มีวงจรการอัปเดตที่เข้มงวด
TOFU เป็นกลยุทธ์ที่ไม่ได้กำหนดค่า Certificate Pinning ล่วงหน้า แต่จะจำใบรับรองเมื่อ การเชื่อมต่อครั้งแรก กับเซิร์ฟเวอร์ วิธีนี้สะดวกสำหรับแอปพลิเคชันที่ไม่ทราบล่วงหน้าว่าจะเชื่อมต่อกับเซิร์ฟเวอร์ใด ข้อเสียคือความเสี่ยงต่อการโจมตีครั้งแรก: หากการเชื่อมต่อครั้งแรกถูกสกัดกั้น ใบรับรองปลอมจะถูกยอมรับว่าเชื่อถือได้ TOFU ใช้ในการเชื่อมต่อ SSH และโปรโตคอล P2P บางอย่าง
บนทั้งสองแพลตฟอร์ม Certificate Pinning ถูกนำไปใช้โดยการสกัดกั้นการเชื่อมต่อ TLS ที่ระดับสแต็กเครือข่าย บน iOS ใช้ตัวแทน URLSession หรือ Alamofire ServerTrustManager บน Android วิธีที่ต้องการคือ OkHttp CertificatePinner ซึ่งอยู่ในไคลเอนต์ HTTP ยอดนิยมและรองรับการกำหนดค่าลายนิ้วมือหลายรายการสำหรับแต่ละโดเมน
func validate(serverTrust: SecTrust,
pinnedHash: String) -> Bool {
guard let certificates = SecTrustCopyCertificateChain(serverTrust)
as? [SecCertificate] else { return false }
for certificate in certificates {
let data = SecCertificateCopyData(certificate)
var hash = Data(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
CC_SHA256($0.baseAddress,
CC_LONG(data.count), &hash)
}
if hash.base64EncodedString() == pinnedHash {
return true
}
}
return false
}
ในฟังก์ชัน Swift ห่วงโซ่ใบรับรองจะถูกแยกจาก serverTrust คำนวณแฮช SHA-256 สำหรับแต่ละใบรับรอง และเปรียบเทียบผลลัพธ์กับที่คาดหวัง การวนซ้ำผ่านใบรับรองทั้งหมดในห่วงโซ่ช่วยให้สามารถนำ pinning ไปใช้ในระดับ CA ระดับกลาง — หากใบรับรองระดับกลางตรงกัน การเชื่อมต่อจะถูกยอมรับ ซึ่งให้ความยืดหยุ่นระหว่างการหมุนเวียนใบรับรองปลายทาง
หากแอปพลิเคชันไม่ได้ใช้ OkHttp สามารถนำ Certificate Pinning ไปใช้ผ่าน X509TrustManager แบบกำหนดเอง วิธีนี้ต้องการโค้ดมากขึ้นแต่ให้การควบคุมกระบวนการตรวจสอบอย่างสมบูรณ์ TrustManager แทนที่เมธอด checkServerTrusted ซึ่งนักพัฒนาจะตรวจสอบใบรับรองเซิร์ฟเวอร์ด้วยตนเองและตัดสินใจว่าจะเชื่อถือหรือไม่ แนะนำเฉพาะสำหรับ สถานการณ์เฉพาะที่ไม่มีไลบรารี OkHttp เท่านั้น
ข้อผิดพลาดที่พบบ่อยที่สุดคือการไม่มี backup pins นักพัฒนาใส่ลายนิ้วมือใบรับรองเพียงรายการเดียว และเมื่อหมดอายุ ผู้ใช้จะสูญเสียการเชื่อมต่อเป็นจำนวนมาก การกำหนดค่าขั้นต่ำที่ยอมรับได้คือสองลายนิ้วมือ: ใบรับรองปัจจุบันและตัวสำรอง เหมาะสมที่สุดคือสาม: ปัจจุบัน ตัวสำรอง และลายนิ้วมือของ CA รูท เป็นตัวเลือกสำรอง
ข้อผิดพลาดที่สองคือการเก็บ pins ในรูปแบบข้อความธรรมดาในโค้ด ผู้โจมตีที่สามารถเข้าถึง APK หรือ IPA สามารถแยกลายนิ้วมือและแทนที่ได้ง่าย แนะนำให้ทำให้แฮชคลุมเครือ: แบ่งสตริงเป็นส่วน ๆ เก็บในทรัพยากรที่เข้ารหัสหรือคำนวณขณะรันไทม์ สำหรับ Android ProGuard พร้อมการทำให้ค่าคงที่สตริงคลุมเครือมีประสิทธิภาพ
ข้อผิดพลาดที่สามคือการปักหมุดที่ระดับใบรับรองพัฒนา ใบรับรองพัฒนาและใช้งานจริงมักจะแตกต่างกัน แต่นักพัฒนามักลืมเปลี่ยน pins เมื่อสร้างบิลด์รีลีส ผลลัพธ์คือแอปพลิเคชันที่ใช้งานจริงไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้ วิธีแก้ไขคือการกำหนดค่า pins แยกต่างหากสำหรับดีบักและรีลีสผ่าน BuildConfig หรือทรัพยากรเฉพาะ flavour
คำถามที่พบบ่อย
SSL Pinning เป็นคำทั่วไปสำหรับการผูกกับใบรับรอง SSL/TLS Certificate Pinning เป็นการนำไปใช้เฉพาะที่ยึดใบรับรอง X.509 เอง ไม่ใช่แค่ คีย์สาธารณะ ความแตกต่างอยู่ที่วัตถุที่ผูก: ใบรับรองเทียบกับคีย์
แนะนำให้เก็บแฮชในทรัพยากรที่มีการทำให้คลุมเครือผ่าน ProGuard (Android) หรือเข้ารหัสผ่าน Keychain (iOS) หลีกเลี่ยงการเก็บ pins ในรูปแบบข้อความธรรมดาใน strings.xml หรือ Info.plist โดยไม่เข้ารหัส
ทุกครั้งที่เปลี่ยนใบรับรองบนเซิร์ฟเวอร์ แนะนำให้เพิ่มลายนิ้วมือใหม่เป็น backup pin 3–6 เดือน ก่อนที่ลายนิ้วมือปัจจุบันจะหมดอายุ และลบอันเก่าหลังการหมุนเวียน อย่างน้อยหนึ่ง backup pin เป็นสิ่งจำเป็น
ได้ ผ่านการคอมไพล์แบบมีเงื่อนไข: pinning ถูกปิดในบิลด์ดีบักและเปิดในบิลด์รีลีส ใช้ BuildConfig.DEBUG บน Android หรือ #if DEBUG บน iOS สำหรับการสลับ อย่าทำผ่านแฟลกรันไทม์ที่ผู้ใช้เข้าถึงได้
ปล่อยอัปเดตแอปพลิเคชันทันทีพร้อมลายนิ้วมือใหม่และเผยแพร่ในร้านค้า ใช้กลไกการอัปเดตบังคับ หาก backup pins รวมลายนิ้วมือของ CA สำรอง คุณสามารถเปลี่ยนไปยังโดเมนอื่นที่มีใบรับรองต่างกันชั่วคราว
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม