Certificate Pinning: คืออะไร กลไกและวิธีการยึด

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-09 เวลาอ่าน: 8 นาที

Certificate Pinning เป็นกลไกการยึดใบรับรองหรือคีย์สาธารณะของเซิร์ฟเวอร์ ซึ่งแอปพลิเคชันใช้ลายนิ้วมือที่ทราบล่วงหน้าเพื่อตรวจสอบการเชื่อมต่อ HTTPS แตกต่างจากห่วงโซ่ความเชื่อถือมาตรฐานผ่าน CA การปักหมุดรับประกันว่าแม้หน่วยงานออกใบรับรองที่ถูกบุกรุกก็ไม่สามารถออกใบรับรองปลอมสำหรับโดเมนของคุณได้ ตาม OWASP MSTG (2025) Certificate Pinning อยู่ในรายการการควบคุมบังคับสำหรับแอปพลิเคชันระดับการป้องกัน L2 การนำไปใช้รวมถึงการเก็บแฮชของใบรับรองในโค้ดและการตรวจสอบในทุกคำขอ

ประเด็นสำคัญ

  • Certificate Pinning — เทคนิคที่แอปพลิเคชันเชื่อถือเฉพาะใบรับรองที่มีลายนิ้วมือที่ทราบล่วงหน้า โดยไม่สนใจห่วงโซ่ CA ทั้งหมด
  • Public Key Pinning — ทางเลือกที่ยึดเฉพาะคีย์สาธารณะ ทำให้การหมุนเวียนเมื่อเปลี่ยนใบรับรองง่ายขึ้น
  • HPKP (HTTP Public Key Pinning) — มาตรฐานที่เลิกใช้แล้วในระดับหัวข้อ HTTP ไม่แนะนำสำหรับโครงการใหม่
  • Backup pins — ลายนิ้วมือสำรองที่รับประกันความต่อเนื่องของการเชื่อมต่อเมื่อใบรับรองหลักเปลี่ยนแปลงหรือหมดอายุ
  • การนำไปใช้ บน iOS ผ่าน SecTrustEvaluate บน Android ผ่าน CertificatePinner ใน OkHttp หรือ TrustManager

Certificate Pinning คืออะไร?

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

เดิมที Certificate Pinning ถูกใช้ในเบราว์เซอร์ผ่านกลไก HPKP (HTTP Public Key Pinning) ซึ่งกำหนดมาตรฐานใน RFC 7469 นักพัฒนาส่งหัวข้อ HTTP Public-Key-Pins พร้อมแฮชของคีย์ที่คาดหวัง และเบราว์เซอร์จะเก็บไว้ตามระยะเวลาที่กำหนด อย่างไรก็ตาม HPKP กลับกลายเป็นอันตราย: ข้อผิดพลาดในการกำหนดค่าเพียงครั้งเดียวสามารถบล็อกไซต์ได้เป็นเดือน ในปี 2018 Chrome ยุติการสนับสนุน HPKP และมาตรฐานปัจจุบันกลายเป็น การนำไปใช้ฝั่งไคลเอนต์ — ภายในแอปพลิเคชันมือถือหรือส่วนขยายเบราว์เซอร์

Certificate Pinning ทำงานอย่างไร?

กระบวนการ Certificate Pinning ประกอบด้วยสามขั้นตอนสำคัญ: การคำนวณลายนิ้วมือ การตรวจสอบการเชื่อมต่อ และการจัดการข้อผิดพลาด ในขั้นตอนการเตรียมการ นักพัฒนาได้รับแฮช SHA-256 ของใบรับรองหรือคีย์สาธารณะของเซิร์ฟเวอร์ที่ใช้งานจริง สำหรับแอปพลิเคชันที่ปฏิบัติตาม GDPR และ PCI DSS ยังจำเป็นต้องยึดลายนิ้วมือของ CA ระดับกลาง ในห่วงโซ่ด้วย

ในทุกคำขอ HTTPS แอปพลิเคชันจะสกัดกั้นการเรียกกลับการรับรองความถูกต้อง TLS แยกใบรับรองของเซิร์ฟเวอร์และคำนวณแฮช SHA-256 แฮชนี้จะถูกเปรียบเทียบกับรายการลายนิ้วมือที่เชื่อถือได้ที่เก็บไว้ หากพบการตรงกัน — การเชื่อมต่อดำเนินต่อไป หากไม่ — แอปพลิเคชันต้อง ยุติการเชื่อมต่อ และรายงานข้อผิดพลาดโดยไม่เปิดเผยรายละเอียดการนำไปใช้แก่ผู้โจมตี

kotlin
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 รายการเพื่อรองรับการหมุนเวียน

Certificate Pinning เทียบกับ Public Key Pinning

เมื่อนำ pinning ไปใช้ ต้องเลือกวัตถุเข้ารหัสที่จะยึด Certificate Pinning ผูกกับใบรับรอง X.509 เอง — หมายเลขซีเรียล ระยะเวลาที่มีผล และห่วงโซ่ทั้งหมด Public Key Pinning ยึดเฉพาะคีย์สาธารณะภายในใบรับรอง โดยไม่สนใจฟิลด์อื่น ๆ ตัวเลือกนี้มีผลกระทบอย่างมากต่อค่าใช้จ่ายในการดำเนินงาน

เกณฑ์Certificate PinningPublic Key Pinning
วัตถุที่ยึดใบรับรอง X.509 ทั้งหมดคีย์สาธารณะ RSA/ECDSA
การหมุนเวียนต้องการอัปเดตทุกครั้งที่ออกใหม่ไม่เปลี่ยนแปลงเมื่อต่ออายุใบรับรองด้วยคีย์เดียวกัน
ความปลอดภัยการผูกที่แม่นยำสูงสุดไวต่อรายละเอียดน้อยกว่า
ความยืดหยุ่นต่ำ — ใบรับรองเปลี่ยนทุก 1–2 ปีสูง — คีย์สามารถใช้งานได้ 5–10 ปี
คำแนะนำสำหรับระบบวิกฤตที่มีการอัปเดตควบคุมสำหรับแอปพลิเคชันมือถือและ API ส่วนใหญ่

Public Key Pinning เป็นตัวเลือกที่ต้องการสำหรับโครงการส่วนใหญ่ คีย์สาธารณะของเซิร์ฟเวอร์มักจะไม่เปลี่ยนแปลงเมื่อออกใบรับรองใหม่ — บริษัทเพียงแค่ลงนามคีย์เก่าด้วยใบรับรองใหม่ ซึ่งหมายความว่าแอปพลิเคชันไม่ต้องการอัปเดตหลังจากเปลี่ยนใบรับรองหากคู่คีย์ไม่เปลี่ยนแปลง ในทางกลับกัน Certificate Pinning แนะนำสำหรับสถานการณ์ที่นักพัฒนาควบคุมทั้งเซิร์ฟเวอร์และโค้ดไคลเอนต์อย่างสมบูรณ์ เช่น ในแอปพลิเคชันองค์กรที่มีวงจรการอัปเดตที่เข้มงวด

Trust On First Use (TOFU)

TOFU เป็นกลยุทธ์ที่ไม่ได้กำหนดค่า Certificate Pinning ล่วงหน้า แต่จะจำใบรับรองเมื่อ การเชื่อมต่อครั้งแรก กับเซิร์ฟเวอร์ วิธีนี้สะดวกสำหรับแอปพลิเคชันที่ไม่ทราบล่วงหน้าว่าจะเชื่อมต่อกับเซิร์ฟเวอร์ใด ข้อเสียคือความเสี่ยงต่อการโจมตีครั้งแรก: หากการเชื่อมต่อครั้งแรกถูกสกัดกั้น ใบรับรองปลอมจะถูกยอมรับว่าเชื่อถือได้ TOFU ใช้ในการเชื่อมต่อ SSH และโปรโตคอล P2P บางอย่าง

การนำไปใช้บน iOS และ Android

บนทั้งสองแพลตฟอร์ม Certificate Pinning ถูกนำไปใช้โดยการสกัดกั้นการเชื่อมต่อ TLS ที่ระดับสแต็กเครือข่าย บน iOS ใช้ตัวแทน URLSession หรือ Alamofire ServerTrustManager บน Android วิธีที่ต้องการคือ OkHttp CertificatePinner ซึ่งอยู่ในไคลเอนต์ HTTP ยอดนิยมและรองรับการกำหนดค่าลายนิ้วมือหลายรายการสำหรับแต่ละโดเมน

swift
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 ระดับกลาง — หากใบรับรองระดับกลางตรงกัน การเชื่อมต่อจะถูกยอมรับ ซึ่งให้ความยืดหยุ่นระหว่างการหมุนเวียนใบรับรองปลายทาง

TrustManager แบบกำหนดเองสำหรับ Android

หากแอปพลิเคชันไม่ได้ใช้ OkHttp สามารถนำ Certificate Pinning ไปใช้ผ่าน X509TrustManager แบบกำหนดเอง วิธีนี้ต้องการโค้ดมากขึ้นแต่ให้การควบคุมกระบวนการตรวจสอบอย่างสมบูรณ์ TrustManager แทนที่เมธอด checkServerTrusted ซึ่งนักพัฒนาจะตรวจสอบใบรับรองเซิร์ฟเวอร์ด้วยตนเองและตัดสินใจว่าจะเชื่อถือหรือไม่ แนะนำเฉพาะสำหรับ สถานการณ์เฉพาะที่ไม่มีไลบรารี OkHttp เท่านั้น

ข้อผิดพลาดในการนำ Certificate Pinning ไปใช้

ข้อผิดพลาดที่พบบ่อยที่สุดคือการไม่มี backup pins นักพัฒนาใส่ลายนิ้วมือใบรับรองเพียงรายการเดียว และเมื่อหมดอายุ ผู้ใช้จะสูญเสียการเชื่อมต่อเป็นจำนวนมาก การกำหนดค่าขั้นต่ำที่ยอมรับได้คือสองลายนิ้วมือ: ใบรับรองปัจจุบันและตัวสำรอง เหมาะสมที่สุดคือสาม: ปัจจุบัน ตัวสำรอง และลายนิ้วมือของ CA รูท เป็นตัวเลือกสำรอง

ข้อผิดพลาดที่สองคือการเก็บ pins ในรูปแบบข้อความธรรมดาในโค้ด ผู้โจมตีที่สามารถเข้าถึง APK หรือ IPA สามารถแยกลายนิ้วมือและแทนที่ได้ง่าย แนะนำให้ทำให้แฮชคลุมเครือ: แบ่งสตริงเป็นส่วน ๆ เก็บในทรัพยากรที่เข้ารหัสหรือคำนวณขณะรันไทม์ สำหรับ Android ProGuard พร้อมการทำให้ค่าคงที่สตริงคลุมเครือมีประสิทธิภาพ

ข้อผิดพลาดที่สามคือการปักหมุดที่ระดับใบรับรองพัฒนา ใบรับรองพัฒนาและใช้งานจริงมักจะแตกต่างกัน แต่นักพัฒนามักลืมเปลี่ยน pins เมื่อสร้างบิลด์รีลีส ผลลัพธ์คือแอปพลิเคชันที่ใช้งานจริงไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้ วิธีแก้ไขคือการกำหนดค่า pins แยกต่างหากสำหรับดีบักและรีลีสผ่าน BuildConfig หรือทรัพยากรเฉพาะ flavour

  • ละเลยห่วงโซ่ใบรับรอง — ตรวจสอบเฉพาะใบรับรองปลายทางโดยไม่พิจารณา CA ระดับกลาง ซึ่งทำให้การเชื่อมต่อขาดระหว่างการหมุนเวียน
  • วันที่แบบตายตัว — วันที่หมดอายุของใบรับรองที่ถูกเขียนตายตัวซึ่งไม่เปลี่ยนแปลงหลังการอัปเดต
  • ไม่มีการตรวจสอบ — ไม่มีการแจ้งเตือนข้อผิดพลาด Certificate Pinning ทำให้ปัญหาถูกค้นพบจากผู้ใช้เท่านั้น
  • TOFU โดยไม่ตรวจสอบ — ใช้ Trust On First Use โดยไม่มีการตรวจสอบเพิ่มเติม ทำให้การโจมตี MITM ครั้งแรกสามารถปักหมุดใบรับรองปลอมได้

คำถามที่พบบ่อย

Certificate Pinning แตกต่างจาก SSL Pinning อย่างไร?

SSL Pinning เป็นคำทั่วไปสำหรับการผูกกับใบรับรอง SSL/TLS Certificate Pinning เป็นการนำไปใช้เฉพาะที่ยึดใบรับรอง X.509 เอง ไม่ใช่แค่ คีย์สาธารณะ ความแตกต่างอยู่ที่วัตถุที่ผูก: ใบรับรองเทียบกับคีย์

วิธีเก็บลายนิ้วมือใบรับรองอย่างปลอดภัยในแอปพลิเคชัน?

แนะนำให้เก็บแฮชในทรัพยากรที่มีการทำให้คลุมเครือผ่าน ProGuard (Android) หรือเข้ารหัสผ่าน Keychain (iOS) หลีกเลี่ยงการเก็บ pins ในรูปแบบข้อความธรรมดาใน strings.xml หรือ Info.plist โดยไม่เข้ารหัส

ควรเปลี่ยนลายนิ้วมือที่ปักหมุดบ่อยแค่ไหน?

ทุกครั้งที่เปลี่ยนใบรับรองบนเซิร์ฟเวอร์ แนะนำให้เพิ่มลายนิ้วมือใหม่เป็น backup pin 3–6 เดือน ก่อนที่ลายนิ้วมือปัจจุบันจะหมดอายุ และลบอันเก่าหลังการหมุนเวียน อย่างน้อยหนึ่ง backup pin เป็นสิ่งจำเป็น

สามารถปิด Certificate Pinning สำหรับการดีบักได้หรือไม่?

ได้ ผ่านการคอมไพล์แบบมีเงื่อนไข: pinning ถูกปิดในบิลด์ดีบักและเปิดในบิลด์รีลีส ใช้ BuildConfig.DEBUG บน Android หรือ #if DEBUG บน iOS สำหรับการสลับ อย่าทำผ่านแฟลกรันไทม์ที่ผู้ใช้เข้าถึงได้

จะทำอย่างไรหากใบรับรองถูกบุกรุก?

ปล่อยอัปเดตแอปพลิเคชันทันทีพร้อมลายนิ้วมือใหม่และเผยแพร่ในร้านค้า ใช้กลไกการอัปเดตบังคับ หาก backup pins รวมลายนิ้วมือของ CA สำรอง คุณสามารถเปลี่ยนไปยังโดเมนอื่นที่มีใบรับรองต่างกันชั่วคราว

สรุป

  • Certificate Pinning — การยึดใบรับรองที่เชื่อถือได้หรือคีย์สาธารณะเพื่อป้องกันการโจมตี MITM ผ่าน CA ปลอม
  • สองแนวทาง — certificate pinning (เข้มงวด กับใบรับรอง) และ public key pinning (ยืดหยุ่น กับคีย์สาธารณะ)
  • Backup pins จำเป็น — อย่างน้อย 2 ลายนิ้วมือเพื่อรับประกันความต่อเนื่องระหว่างการหมุนเวียนใบรับรอง
  • OkHttp CertificatePinner — วิธีการนำไปใช้มาตรฐานบน Android ที่รองรับหลาย pins
  • URLSessionDelegate — วิธีหลักบน iOS ด้วยการตรวจสอบ SecTrust ด้วยตนเองและแฮช SHA-256
  • ข้อผิดพลาดทั่วไป — ขาด backup pins เก็บโดยไม่ทำให้คลุมเครือ สับสนการกำหนดค่าดีบัก/รีลีส
  • คำแนะนำ — ใช้ public key pinning สำหรับโครงการส่วนใหญ่และ Certificate Pinning สำหรับระบบวิกฤตเท่านั้น

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม