Network Security Certificate คืออะไร?
ในบริบทของ Mobile/Network Security มี 2 ความหมายหลัก:
- Digital Certificate (SSL/TLS Certificate): ใบรับรองดิจิทัลสำหรับยืนยันตัวตนเซิร์ฟเวอร์/อุปกรณ์ และเข้ารหัสการสื่อสาร (HTTPS, TLS, Mutual TLS, 802.1X/EAP-TLS)
- Network Security Configuration (Android): ฟีเจอร์ Android 7.0+ (API 24+) ที่ให้แอปกำหนดการตั้งค่าความปลอดภัยเครือข่ายผ่านไฟล์ XML โดยไม่ต้องแก้โค้ด
Part 1: ติดตั้ง Certificate บน Android (User/CA Certificate)
สถานการณ์ที่ต้องติดตั้ง:
- Enterprise Wi-Fi (802.1X EAP-TLS) ต้องการ Client Certificate
- Corporate VPN (Mutual TLS)
- Intercept HTTPS Traffic สำหรับ Debug/Testing (Burp Suite, Charles Proxy, mitmproxy)
- Private CA ขององค์กร (Private PKI)
วิธีติดตั้ง User Certificate (.pfx/.p12)
- Copy ไฟล์ .pfx/.p12 ไปที่ Internal Storage ของโทรศัพท์
- Settings > Security > Encryption & credentials (หรือ Security & location > Encryption & credentials)
- เลือก "Install a certificate" > "CA certificate" (สำหรับ Root CA) หรือ "VPN & app user certificate" (สำหรับ Client Cert)
- ใส่รหัสล็อกหน้าจอ (PIN/Pattern) ถ้ายังไม่มี
- เลือกไฟล์ .pfx/.p12 → ใส่รหัสผ่านของ Certificate (ถ้ามี)
- ตั้งชื่อ Certificate (เช่น "Corporate WiFi Cert") → OK
วิธีติดตั้ง CA Certificate (.crt/.cer/.pem)
- Settings > Security > Encryption & credentials > Install a certificate > CA certificate
- เลือกไฟล์ .crt/.cer/.pem
- ตั้งชื่อ (เช่น "Company Root CA") → OK
- Certificate จะอยู่ใน "User" tab (ไม่ใช่ System)
Part 2: Network Security Configuration (Android App Development)
สำหรับนักพัฒนาแอป Android: สร้างไฟล์ res/xml/network_security_config.xml
ตัวอย่างไฟล์พื้นฐาน
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.mycompany.com</domain>
<trust-anchors>
<certificates src="system" />
<certificates src="@raw/my_ca" />
</trust-anchors>
<pin-set expiration="2025-01-01">
<pin digest="SHA-256">base64_encoded_spki_hash_1</pin>
<pin digest="SHA-256">base64_encoded_spki_hash_2</pin>
</pin-set>
</domain-config>
<debug-overrides>
<trust-anchors>
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
ลงทะเบียนใน AndroidManifest.xml
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
คีย์ฟีเจอร์สำคัญ
| Element | คำอธิบาย |
|---|---|
base-config | ค่าเริ่มต้นสำหรับทุก Domain ที่ไม่ได้ระบุใน domain-config |
domain-config | ตั้งค่าเฉพาะ Domain (รองรับ includeSubdomains) |
trust-anchors | กำหนด CA ที่ไว้ใจ: src="system" (System CA), src="user" (User-installed CA), src="@raw/ca" (App-bundled CA) |
pin-set | Certificate Pinning: ระบุ SPKI Hash ที่ยอมรับ ป้องกัน MITM แม้ CA ถูก Compromise |
cleartextTrafficPermitted | true/false: อนุญาต HTTP แบบไม่เข้ารหัส (Default: false ตั้งแต่ Android 9) |
debug-overrides | ตั้งค่าพิเศษสำหรับ Debug Build (เช่น ไว้ใจ User CA สำหรับ Proxy Testing) |
Part 3: Certificate Pinning - ป้องกัน Man-in-the-Middle
Certificate Pinning (Public Key Pinning) คือการ "หมุด" (Pin) Public Key หรือ SPKI Hash ของเซิร์ฟเวอร์ที่คาดหวังไว้ในแอป หากเซิร์ฟเวอร์ส่ง Certificate ที่มี Public Key ต่างจากที่ Pin ไว้ → Connection จะล้มเหลว แม้ Certificate จะถูกต้องและ Sign โดย CA ที่ไว้ใจก็ตาม
วิธีสร้าง Pin (SPKI SHA-256 Base64)
# จาก Certificate ไฟล์ .crt
openssl x509 -in server.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl base64
# จาก Private Key .key
openssl rsa -in server.key -pubout -outform der | openssl dgst -sha256 -binary | openssl base64
Best Practices สำหรับ Pinning
- Pin Backup Key ไว้อย่างน้อย 1-2 Keys (Key Rotation)
- ตั้ง
expirationให้หมดอายุก่อน Certificate หมดอายุ - ใช้
debug-overridesเพื่ออนุญาต User CA ใน Debug Build เท่านั้น - Test อย่างละเอียดก่อน Release (Pin ผิด = App ใช้งานไม่ได้ทั้งหมด)
Part 4: Cleartext Traffic (HTTP แบบไม่เข้ารหัส)
ตั้งแต่ Android 9 (API 28) Cleartext Traffic ถูกบล็อกโดย Default (cleartextTrafficPermitted="false")
หากต้องการอนุญาต HTTP สำหรับ Domain เฉพาะ (ไม่แนะนำ Production)
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">legacy.internal.company.com</domain>
</domain-config>
แนะนำ: ย้ายไป HTTPS ทั้งหมด ใช้ Let's Encrypt (ฟรี) หรือ Private CA
Part 5: จัดการ Certificate ใน Enterprise (MDM/EMM)
- ใช้ MDM (Intune, VMware Workspace ONE, Samsung Knox, Google Endpoint Management) Deploy Certificate ไปยังอุปกรณ์อัตโนมัติ
- SCEP (Simple Certificate Enrollment Protocol) สำหรับออก Certificate ให้อุปกรณ์อัตโนมัติ
- Managed Configurations สำหรับแอป Enterprise
- Certificate Revocation Checking (CRL/OCSP)
สรุป
User: ติดตั้ง Certificate ผ่าน Settings > Security > Install Certificate
Developer: ใช้ network_security_config.xml กำหนด Trust Anchors, Pinning, Cleartext Policy
Enterprise: Deploy ผ่าน MDM/SCEP, ใช้ Private PKI, Enforce Pinning
Security: ห้าม Cleartext (HTTP), Pinning Production Certs, Rotate Keys ก่อนหมดอายุ