SSL/TLS เป็นโปรโตคอลการเข้ารหัสที่เข้ารหัสข้อมูลระหว่างแอปพลิเคชันมือถือและเซิร์ฟเวอร์ เพื่อรับประกันความลับและความสมบูรณ์ของการรับส่งข้อมูล ตามข้อมูลของ Apple (2026) App Transport Security จะบล็อกการเชื่อมต่อที่ต่ำกว่า TLS 1.2 โดยค่าเริ่มต้นบนอุปกรณ์ iOS ทั้งหมด TLS 1.3 ลดเวลาในการจับมือกันลง 2 เท่าเมื่อเทียบกับ TLS 1.2 ซึ่งช่วยปรับปรุง UX ของแอปพลิเคชันมือถือ
ประเด็นสำคัญ
SSL (Secure Sockets Layer) และ TLS (Transport Layer Security) เป็นโปรโตคอลการเข้ารหัสที่รับประกันการส่งข้อมูลอย่างปลอดภัยผ่านเครือข่าย SSL ที่พัฒนาโดย Netscape ในช่วงปี 1990 ถือว่าล้าสมัยหลังจากเวอร์ชัน 3.0 เนื่องจากช่องโหว่ POODLE และ BEAST TLS ซึ่งเป็นตัวต่อจาก SSL ได้ผ่านเวอร์ชัน 1.0, 1.1, 1.2 และ 1.3 — มีเพียง TLS 1.2 และ TLS 1.3 เท่านั้นที่ถือว่าเป็นปัจจุบัน แพลตฟอร์มมือถือสมัยใหม่ทั้งหมดกำหนดให้ใช้ TLS สำหรับการเชื่อมต่อเครือข่าย และ App Store และ Google Play ตรวจสอบสิ่งนี้ในขั้นตอนการตรวจสอบ
หากไม่มี TLS การรับส่งข้อมูลระหว่างแอปพลิเคชันและเซิร์ฟเวอร์จะถูกส่งเป็น ข้อความธรรมดา — ใครก็ตามบนเครือข่าย Wi-Fi เดียวกันสามารถดักจับข้อมูลการเข้าสู่ระบบ รหัสผ่าน โทเค็น และข้อมูลส่วนบุคคลของผู้ใช้โดยใช้ Wireshark หรือ tcpdump TLS เข้ารหัสข้อมูลทั้งหมดที่ส่ง (การเข้ารหัสระดับ Transport) และตรวจสอบความถูกต้องของเซิร์ฟเวอร์ผ่านห่วงโซ่ของใบรับรอง X.509 ตามข้อมูลของ IETF (2018) TLS 1.3 ใช้เฉพาะการเข้ารหัส AEAD ที่ทันสมัย (AES-GCM, ChaCha20-Poly1305) โดยไม่รวมอัลกอริทึมที่ล้าสมัยเช่น RC4 และ 3DES
HTTPS (HTTP Secure) คือ HTTP บน TLS เมื่อแอปพลิเคชันมือถือทำคำขอผ่าน https:// มันจะสร้างการเชื่อมต่อ TLS กับเซิร์ฟเวอร์ก่อน จากนั้นจึงส่งส่วนหัว HTTP และเนื้อหาคำขอผ่านช่องทางที่เข้ารหัสแล้ว หากไม่มี HTTPS ไม่มี API ที่จริงจังใดควรทำงาน — นี่คือสุขอนามัยด้านความปลอดภัยพื้นฐาน ตามข้อมูลของ OWASP (2026) การเชื่อมต่อที่ไม่ปลอดภัยอยู่ใน 3 อันดับแรกของช่องโหว่ของแอปพลิเคชันมือถือ
TLS Handshake เป็นกระบวนการสร้างการเชื่อมต่อที่ปลอดภัยระหว่างไคลเอนต์และเซิร์ฟเวอร์ ทั้งสองฝ่ายเจรจาเวอร์ชันโปรโตคอล เลือกชุดการเข้ารหัส (cipher suite) แลกเปลี่ยนคีย์ผ่านการเข้ารหัสแบบอสมมาตร และตรวจสอบใบรับรอง ใน TLS 1.2 การจับมือกันต้องใช้เวลา 2 Round Trip Time (2 RTT): ไคลเอนต์ → เซิร์ฟเวอร์ด้วย ClientHello, เซิร์ฟเวอร์ → ไคลเอนต์ด้วย ServerHello และ Certificate จากนั้นข้อความ Finished สุดท้าย TLS 1.3 ลดกระบวนการนี้เหลือ 1 RTT
ขั้นตอนแรก: ClientHello — ไคลเอนต์ส่งเวอร์ชัน TLS ที่รองรับ รายการชุดการเข้ารหัส และหมายเลขสุ่ม เซิร์ฟเวอร์ตอบกลับด้วย ServerHello โดยเลือกเวอร์ชันและชุดการเข้ารหัส ส่งใบรับรอง X.509 (Certificate) และข้อความ ServerHelloDone ไคลเอนต์ตรวจสอบใบรับรองผ่านห่วงโซ่ของหน่วยงานออกใบรับรอง (CA) ที่เชื่อถือได้ สร้าง pre-master secret เข้ารหัสด้วยคีย์สาธารณะจากใบรับรอง และส่งไปยังเซิร์ฟเวอร์ใน ClientKeyExchange หลังจากนั้น ทั้งสองฝ่ายสร้างคีย์เซสชันและแลกเปลี่ยนข้อความ ChangeCipherSpec และ Finished ตั้งแต่จุดนี้เป็นต้นไป ข้อมูลทั้งหมดจะถูกเข้ารหัสแบบสมมาตร
import Security
let url = URL(string: "https://api.example.com")!
let session = URLSession(configuration: .default,
delegate: self,
delegateQueue: nil)
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition,
URLCredential?) -> Void
) {
let trust = challenge.protectionSpace.serverTrust
guard let trust else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
completionHandler(.useCredential, URLCredential(trust: trust))
}
ตัวอย่างการจัดการ URLAuthenticationChallenge บน iOS ผ่าน URLSessionDelegate เมธอดนี้จะถูกเรียกระหว่าง TLS Handshake แต่ละครั้ง ทำให้แอปพลิเคชันสามารถตรวจสอบใบรับรองเซิร์ฟเวอร์แบบกำหนดเองได้ สำหรับการใช้งานในโปรดักชัน ให้เพิ่มการตรวจสอบใบรับรองผ่าน SecTrustEvaluateWithError และเปรียบเทียบกับลายนิ้วมือที่บันทึกไว้ล่วงหน้า — จากนั้นจึงเรียก useCredential
TLS 1.3 (RFC 8446, 2018) เป็นการอัปเดตโปรโตคอลครั้งใหญ่ครั้งแรกในรอบ 10 ปี การปรับปรุงหลัก: การจับมือกันลดลงเหลือ 1 RTT (0 RTT สำหรับการเชื่อมต่อซ้ำ) การลบชุดการเข้ารหัสที่ล้าสมัย (การแลกเปลี่ยนคีย์ RSA, โหมด CBC) การบังคับใช้ Perfect Forward Secrecy (PFS) และการป้องกันการโจมตีแบบลดระดับผ่าน signed transcript ตามข้อมูลของ Qualys SSL Labs (2026) TLS 1.3 ให้การปกป้องแม้ว่าคีย์เซิร์ฟเวอร์ระยะยาวจะถูกบุกรุกก็ตาม ต้องขอบคุณ PFS
| คุณลักษณะ | TLS 1.2 | TLS 1.3 |
|---|---|---|
| การจับมือกัน | 2 RTT (เต็ม) | 1 RTT (0 RTT ด้วย PSK) |
| ชุดการเข้ารหัส | 30+ การผสม (RSA, DH, ECDH) | 5 ชุด AEAD (AES-GCM, ChaCha20) |
| Forward Secrecy | ไม่บังคับ (DHE, ECDHE) | บังคับ (ทุกชุด) |
| การรองรับ iOS | iOS 5+ | iOS 12+ |
| การรองรับ Android | Android 4.0+ | Android 10+ |
| อัลกอริทึมที่ล้าสมัย | RSA, CBC, RC4, 3DES | ถูกลบทั้งหมด |
0-RTT (Zero Round Trip Time) เป็นคุณสมบัติของ TLS 1.3 ที่อนุญาตให้ไคลเอนต์ส่งข้อมูลทันทีพร้อมกับ ClientHello ในการเชื่อมต่อซ้ำผ่าน PSK (Pre-Shared Key) ซึ่งช่วยเร่งการโหลดหน้าจอถัดไปในแอปพลิเคชันมือถือ โดยเฉพาะอย่างยิ่งกับคำขอที่บ่อยครั้งไปยังเซิร์ฟเวอร์เดียวกัน อย่างไรก็ตาม ข้อมูล 0-RTT ไม่ได้รับการปกป้องจากการโจมตีแบบ replay — สามารถถูกดักจับและส่งซ้ำได้ ใช้ 0-RTT เฉพาะกับคำขอที่ idempotent (GET, PUT) ที่ไม่มีผลข้างเคียง
App Transport Security (ATS) เป็นกลไกของ Apple ที่กำหนดให้ใช้การเชื่อมต่อ HTTPS กับ TLS 1.2 หรือสูงกว่า ซึ่งเปิดใช้งานโดยค่าเริ่มต้นตั้งแต่ iOS 9 ATS บล็อกการเชื่อมต่อ HTTP ทั้งหมดและ HTTPS ที่มี TLS ต่ำกว่า 1.2 นักพัฒนาสามารถกำหนดค่าข้อยกเว้นใน Info.plist ผ่าน NSAppTransportSecurity สำหรับโดเมนเฉพาะ แต่ Apple แนะนำให้ลดข้อยกเว้นให้น้อยที่สุดและใช้ HTTPS ทุกที่ การละเมิดข้อกำหนด ATS เป็นเหตุผลในการปฏิเสธแอประหว่างการตรวจสอบ App Store
<!-- Info.plist — App Transport Security -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<key>cdn.example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
</dict>
</dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
การกำหนดค่า ATS ใน Info.plist NSAllowsArbitraryLoads ถูกตั้งค่าเป็น false — การเชื่อมต่อทั้งหมดต้องใช้ HTTPS สำหรับโดเมน cdn.example.com มีการระบุเวอร์ชัน TLS ขั้นต่ำ 1.2, NSAllowsLocalNetworking=true อนุญาต HTTP สำหรับเครือข่ายท้องถิ่น (มีประโยชน์สำหรับเซิร์ฟเวอร์พัฒนา) Apple แนะนำอย่างยิ่งให้ไม่เปิดใช้งาน NSAllowsArbitraryLoads โดยไม่มี NSExceptionDomains — ควรเป็นข้อยกเว้น ไม่ใช่กฎทั่วไป
Network Security Config เป็นกลไกของ Android สำหรับกำหนดค่า HTTPS และ TLS โดยไม่ต้องเปลี่ยนโค้ด Java/Kotlin การกำหนดค่าถูกระบุในไฟล์ network_security_config.xml และเชื่อมต่อใน AndroidManifest ผ่านแอตทริบิวต์ android:networkSecurityConfig รองรับการกำหนดค่าใบรับรองที่เชื่อถือได้ (CA ผู้ใช้และระบบ), Certificate Pinning, การปิดใช้งาน HTTP ข้อความธรรมดา, การแทนที่การดีบัก และการเปลี่ยนเส้นทางการรับส่งข้อมูล
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-01-01">
<pin digest="SHA-256">
47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
</pin>
</pin-set>
</domain-config>
</network-security-config>
Network Security Config สำหรับ Android base-config บล็อกการรับส่งข้อมูลข้อความธรรมดาและเชื่อถือเฉพาะใบรับรอง CA ของระบบ (ไม่มีใบรับรองผู้ใช้ — ป้องกันการติดตั้งใบรับรอง MitM โดยผู้ใช้) domain-config สำหรับ api.example.com มี pin-set พร้อมลายนิ้วมือ SHA-256 ของใบรับรอง หากใบรับรองเซิร์ฟเวอร์เปลี่ยนแปลงก่อนวันที่หมดอายุที่ระบุ การเชื่อมต่อจะถูกปฏิเสธ — นี่เป็นรูปแบบที่เข้มงวดของ Certificate Pinning
Certificate Pinning เป็นเทคนิคการปักหมุดใบรับรองหรือคีย์สาธารณะของเซิร์ฟเวอร์ในโค้ดแอปพลิเคชัน ระหว่าง TLS Handshake แต่ละครั้ง ไคลเอนต์จะเปรียบเทียบใบรับรองเซิร์ฟเวอร์กับลายนิ้วมือที่บันทึกไว้ล่วงหน้า (แฮช SHA-256) แม้ว่าผู้โจมตีจะได้รับใบรับรอง CA ที่เชื่อถือได้หรือบุกรุกหน่วยงานออกใบรับรอง พวกเขาไม่สามารถโจมตีแบบ MitM ได้ — แอปพลิเคชันตรวจสอบลายนิ้วมือเฉพาะ ไม่ใช่ห่วงโซ่ CA ซึ่งมีความสำคัญอย่างยิ่งสำหรับแอปพลิเคชันทางการเงินและแอปที่จัดการกับข้อมูลที่ละเอียดอ่อน
Certificate Pinning ต้องการความระมัดระวัง: เมื่อใบรับรองเซิร์ฟเวอร์เปลี่ยนแปลง แอปพลิเคชันเวอร์ชันเก่าทั้งหมดจะหยุดเชื่อมต่อ ขอแนะนำให้เก็บลายนิ้วมือสำรองหลายรายการ (หลัก + สำรอง) ระบุวันที่หมดอายุของ pin-set และใช้กลไกสำรองผ่านการตรวจสอบ CA มาตรฐาน ทางเลือกคือ Trust On First Use (TOFU) ซึ่งแอปพลิเคชันจะจดจำใบรับรองในการเชื่อมต่อครั้งแรกและเตือนผู้ใช้เมื่อมีการเปลี่ยนแปลง ตามข้อมูลของ OWASP (2026) การไม่มี Certificate Pinning อยู่ใน 3 อันดับแรกของช่องโหว่ของแอปพลิเคชันมือถือ (M3: การสื่อสารที่ไม่ปลอดภัย)
ใน Alamofire 5+ การกำหนดค่า Certificate Pinning ทำผ่าน ServerTrustManager กับ PinnedCertificatesTrustEvaluator (ตรวจสอบใบรับรองทั้งหมด) หรือ PublicKeysTrustEvaluator (เฉพาะคีย์สาธารณะ) คีย์สาธารณะดีกว่า — ไม่เปลี่ยนแปลงเมื่อต่ออายุใบรับรองกับ CA เดียวกัน สร้าง ServerTrustManager ด้วยพจนานุกรม [host: evaluator] ส่งต่อไปยัง Session และใช้สำหรับคำขอทั้งหมดไปยัง API ที่ป้องกัน
คำถามที่พบบ่อย
SSL เป็นโปรโตคอลที่ล้าสมัย (เวอร์ชัน 2.0 และ 3.0) ซึ่งถือว่าไม่ปลอดภัยเนื่องจากช่องโหว่ POODLE และ BEAST TLS เป็นตัวต่อจาก SSL เริ่มต้นด้วย TLS 1.0 (RFC 2246, 1999) “ใบรับรอง SSL” สมัยใหม่ใดๆ ก็คือใบรับรอง X.509 ที่ใช้โดยโปรโตคอล TLS SSL 3.0 ถูกห้ามในระบบปฏิบัติการและเบราว์เซอร์สมัยใหม่ทั้งหมด
App Transport Security เป็นข้อกำหนดด้านความปลอดภัยของ Apple สำหรับแอปพลิเคชัน HTTP ส่งข้อมูลเป็นข้อความธรรมดา ทำให้สามารถดักจับโทเค็นและข้อมูลส่วนบุคคลของผู้ใช้บนเครือข่าย Wi-Fi สาธารณะ ATS จะบล็อก HTTP และ HTTPS ด้วย TLS ต่ำกว่า 1.2 โดยค่าเริ่มต้น ปกป้องผู้ใช้แม้ไม่มีการดำเนินการจากนักพัฒนา
ใช้ SSL Labs (ssllabs.com/ssltest) หรือบรรทัดคำสั่ง: openssl s_client -tls1_3 -connect example.com:443 บนแพลตฟอร์มคลาวด์ส่วนใหญ่ (AWS CloudFront, Cloudflare, Nginx 1.19+, Caddy) TLS 1.3 เปิดใช้งานโดยค่าเริ่มต้น บน Android 10+ การรองรับถูกสร้างไว้ในผู้ให้บริการระบบ Conscrypt
ใบรับรองที่เซ็นชื่อด้วยตนเอง คือใบรับรองที่เซ็นชื่อโดยตัวเอง ไม่ใช่โดยหน่วยงานออกใบรับรอง ไม่สามารถใช้ในโปรดักชันได้ — ระบบปฏิบัติการมือถือไม่เชื่อถือใบรับรองดังกล่าว ใช้สำหรับการพัฒนาในพื้นที่: เพิ่มใบรับรองลงในรายการที่เชื่อถือได้ผ่าน MDM หรือใช้บิลด์ดีบักที่ปิดการตรวจสอบ
สร้าง ServerTrustManager ด้วย PinnedCertificatesTrustEvaluator หรือ PublicKeysTrustEvaluator ตัวแรกตรวจสอบใบรับรองทั้งหมด ตัวที่สอง — เฉพาะคีย์สาธารณะ (ดีกว่า) ส่งผู้จัดการไปยัง Session(configuration: serverTrustManager:) และใช้เซสชันสำหรับคำขอ API ทั้งหมด
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม