ฟีเจอร์การกำหนดค่าความปลอดภัยของเครือข่ายช่วยให้คุณปรับแต่งการตั้งค่าความปลอดภัยของเครือข่ายของแอปได้ ในไฟล์การกำหนดค่าที่ปลอดภัยและประกาศ โดยไม่ต้องแก้ไขโค้ดของแอป คุณกำหนดค่าการตั้งค่าเหล่านี้สำหรับโดเมนที่เฉพาะเจาะจงและสำหรับแอปที่เฉพาะเจาะจงได้ ความสามารถหลักของฟีเจอร์นี้มีดังนี้
- Trust Anchor ที่กำหนดเอง: กำหนดผู้ออกใบรับรอง (CA) ที่เชื่อถือได้สำหรับการเชื่อมต่อที่ปลอดภัยของแอป เช่น การเชื่อถือใบรับรองที่ลงนามด้วยตนเองที่เฉพาะเจาะจงหรือ การจำกัดชุด CA สาธารณะที่แอปเชื่อถือ
- การลบล้างเฉพาะการแก้ไขข้อบกพร่อง: แก้ไขข้อบกพร่องการเชื่อมต่อที่ปลอดภัยในแอปได้อย่างปลอดภัยโดยไม่มีความเสี่ยงเพิ่มเติมต่อ ฐานการติดตั้ง
- การเลือกไม่ใช้การรับส่งข้อมูลข้อความธรรมดา: ปกป้องแอปจากการใช้การรับส่งข้อมูลข้อความธรรมดา (ที่ไม่ได้เข้ารหัส) โดยไม่ตั้งใจ
- ความโปร่งใสของใบรับรอง: จำกัดการเชื่อมต่อที่ปลอดภัยของแอปให้ใช้ใบรับรองที่บันทึกแล้วอย่างพิสูจน์ได้
- การปักหมุดใบรับรอง: จำกัดการเชื่อมต่อที่ปลอดภัยของแอปกับใบรับรองที่เฉพาะเจาะจง
เพิ่มไฟล์การกำหนดค่าการรักษาความปลอดภัยเครือข่าย
ฟีเจอร์การกำหนดค่าความปลอดภัยเครือข่ายใช้ไฟล์ XML ที่คุณระบุการตั้งค่าสำหรับแอป คุณต้องรวมรายการในไฟล์ Manifest ของแอปเพื่อชี้ไปยังไฟล์นี้ ข้อมูลโค้ดต่อไปนี้จากไฟล์ Manifest แสดงวิธีสร้างรายการนี้
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
ปรับแต่ง CA ที่เชื่อถือได้
คุณอาจต้องการให้แอปเชื่อถือชุด CA ที่กำหนดเองแทนค่าเริ่มต้นของแพลตฟอร์ม สาเหตุที่พบบ่อยที่สุด มีดังนี้
- การเชื่อมต่อกับโฮสต์ที่มี CA ที่กำหนดเอง เช่น CA ที่ลงนามด้วยตนเองหรือออก ภายในบริษัท
- จำกัดชุด CA ให้มีเฉพาะ CA ที่คุณเชื่อถือแทนที่จะเป็น CA ที่ติดตั้งไว้ล่วงหน้าทั้งหมด
- การเชื่อถือ CA เพิ่มเติมที่ไม่ได้รวมอยู่ในระบบ
โดยค่าเริ่มต้น การเชื่อมต่อที่ปลอดภัย (ใช้โปรโตคอล เช่น TLS และ HTTPS) จากแอปทั้งหมดจะเชื่อถือ CA ของระบบที่ติดตั้งไว้ล่วงหน้า
และแอปที่กำหนดเป้าหมายเป็น Android 6.0 (ระดับ API 23) และต่ำกว่าจะเชื่อถือ
ที่เก็บ CA ที่ผู้ใช้เพิ่มโดยค่าเริ่มต้นด้วย คุณปรับแต่งการเชื่อมต่อของแอปได้โดยใช้
base-config (สำหรับการปรับแต่งทั้งแอป) หรือ domain-config (สำหรับการ
ปรับแต่งต่อโดเมน)
กำหนดค่า CA ที่กำหนดเอง
คุณอาจต้องการเชื่อมต่อกับโฮสต์ที่ใช้ใบรับรอง SSL แบบ Self-signed หรือโฮสต์ที่
ผู้ออกใบรับรอง SSL เป็น CA ที่ไม่ใช่แบบสาธารณะซึ่งคุณเชื่อถือ เช่น CA ภายในของบริษัท
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีกำหนดค่าแอปสำหรับ CA ที่กำหนดเองใน
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config> </network-security-config>
เพิ่มใบรับรอง CA ที่ลงนามด้วยตนเองหรือ CA ที่ไม่ใช่สาธารณะในรูปแบบ PEM หรือ DER ไปยัง
res/raw/my_ca
จำกัดชุด CA ที่เชื่อถือได้
หากไม่ต้องการให้แอปเชื่อถือ CA ทั้งหมดที่ระบบเชื่อถือ คุณสามารถระบุ ชุด CA ที่ลดลงเพื่อเชื่อถือแทนได้ ซึ่งจะช่วยปกป้องแอปจากใบรับรองที่ฉ้อโกงซึ่งออกโดย CA อื่นๆ
การกำหนดค่าเพื่อจำกัดชุด CA ที่เชื่อถือได้จะคล้ายกับ
การเชื่อถือ CA ที่กำหนดเองสำหรับโดเมนที่เฉพาะเจาะจง ยกเว้นว่าจะมี CA หลายรายการ
ในทรัพยากร ข้อมูลโค้ดต่อไปนี้แสดงวิธีจำกัดชุด CA ที่เชื่อถือได้ของแอปใน res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">secure.example.com</domain> <domain includeSubdomains="true">cdn.example.com</domain> <trust-anchors> <certificates src="@raw/trusted_roots"/> </trust-anchors> </domain-config> </network-security-config>
เพิ่ม CA ที่เชื่อถือได้ในรูปแบบ PEM หรือ DER ไปยัง res/raw/trusted_roots โปรดทราบว่าหาก
คุณใช้รูปแบบ PEM ไฟล์ต้องมีข้อมูล PEM เท่านั้นและไม่มีข้อความเพิ่มเติม คุณยังระบุองค์ประกอบ
<certificates>
หลายรายการแทนรายการเดียวได้ด้วย
เชื่อถือ CA เพิ่มเติม
คุณอาจต้องการให้แอปเชื่อถือ CA เพิ่มเติมที่ระบบไม่เชื่อถือ เช่น ในกรณีที่
ระบบยังไม่มี CA หรือ CA ไม่เป็นไปตามข้อกำหนดสำหรับการรวมไว้ใน
ระบบ Android คุณระบุแหล่งที่มาของใบรับรองหลายแหล่งสำหรับการกำหนดค่าได้ใน
res/xml/network_security_config.xml โดยใช้โค้ดที่คล้ายกับตัวอย่างต่อไปนี้
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="@raw/extracas"/> <certificates src="system"/> </trust-anchors> </base-config> </network-security-config>
กำหนดค่า CA สำหรับการแก้ไขข้อบกพร่อง
เมื่อแก้ไขข้อบกพร่องของแอปที่เชื่อมต่อผ่าน HTTPS คุณอาจต้องการเชื่อมต่อกับเซิร์ฟเวอร์การพัฒนาในเครื่องที่ไม่มีใบรับรอง SSL สำหรับเซิร์ฟเวอร์ที่ใช้งานจริง หากต้องการรองรับการดำเนินการนี้
โดยไม่ต้องแก้ไขโค้ดของแอป คุณสามารถระบุ CA สำหรับการแก้ไขข้อบกพร่องเท่านั้น ซึ่งจะเชื่อถือได้เฉพาะเมื่อ
android:debuggable เป็น
true โดยใช้ debug-overrides โดยปกติแล้ว IDE และเครื่องมือบิลด์จะตั้งค่า
แฟล็กนี้โดยอัตโนมัติสำหรับการบิลด์ที่ไม่ใช่เวอร์ชันที่เผยแพร่
วิธีนี้ปลอดภัยกว่าโค้ดแบบมีเงื่อนไขปกติ เนื่องจาก App Store ไม่ยอมรับแอปที่ทำเครื่องหมายว่าแก้ไขข้อบกพร่องได้เพื่อเป็นการรักษาความปลอดภัย
ข้อมูลที่ตัดตอนมาด้านล่างแสดงวิธีกําหนด CA ที่ใช้ในการแก้ไขข้อบกพร่องเท่านั้นใน
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors> <certificates src="@raw/debug_cas"/> </trust-anchors> </debug-overrides> </network-security-config>
ความโปร่งใสของใบรับรอง
หมายเหตุ: การรองรับความโปร่งใสของใบรับรองใช้ได้ใน Android 16 (ระดับ API 36) ขึ้นไปเท่านั้น
ความโปร่งใสของใบรับรอง (CT, RFC 6962) เป็นมาตรฐานอินเทอร์เน็ต ที่ออกแบบมาเพื่อเพิ่มความปลอดภัยของใบรับรองดิจิทัล โดยกำหนดให้ CA ต้องส่งใบรับรองที่ออกทั้งหมดไปยังบันทึกสาธารณะที่บันทึกใบรับรองเหล่านั้น ซึ่งจะช่วยเพิ่มความโปร่งใสและความรับผิดชอบในกระบวนการออกใบรับรอง
การเก็บรักษาบันทึกที่ตรวจสอบได้ของใบรับรองทั้งหมดทำให้ผู้ไม่ประสงค์ดีปลอมแปลงใบรับรองหรือ CA ออกใบรับรองโดยไม่ได้ตั้งใจได้ยากขึ้นอย่างมาก ซึ่งช่วยปกป้อง ผู้ใช้จากการโจมตีแบบแทรกกลางการสื่อสารและภัยคุกคามด้านความปลอดภัยอื่นๆ ดูข้อมูลเพิ่มเติมได้ที่คำอธิบายใน transparency.dev ดูข้อมูลเพิ่มเติมเกี่ยวกับ การปฏิบัติตามข้อกำหนด CT ใน Android ได้ที่นโยบาย CT ของ Android
ลักษณะการทำงานเริ่มต้นของความโปร่งใสของใบรับรองจะขึ้นอยู่กับระดับ API ดังนี้
- ตั้งแต่ Android 17 (API ระดับ 37) เป็นต้นไป ระบบจะเปิดใช้ความโปร่งใสของใบรับรองโดยค่าเริ่มต้น แอปสามารถเลือกไม่ใช้ฟีเจอร์นี้ได้ทั้งทั่วโลกหรือต่อโดเมน
- ใน Android 16 (ระดับ API 36) การตรวจสอบความโปร่งใสของใบรับรองจะปิดใช้โดยค่าเริ่มต้น แอปสามารถ เลือกใช้ฟีเจอร์ได้ทั้ง ทั่วโลกหรือตามโดเมน
- ใน Android 15 (ระดับ API 35) และต่ำกว่า ความโปร่งใสของใบรับรองจะใช้ไม่ได้
เลือกไม่ใช้ความโปร่งใสของใบรับรอง
หมายเหตุ: สำหรับ Android 16 (API ระดับ 36) ให้เลือกใช้ความโปร่งใสของใบรับรองโดยการตั้งค่า
<certificateTransparency enabled="true"/> (ปิดใช้โดยค่าเริ่มต้น)
หากต้องการให้แอปเชื่อมต่อกับปลายทางโดยไม่ต้องกำหนดให้บันทึกใบรับรองลงในบันทึกความโปร่งใสของใบรับรอง คุณสามารถเลือกไม่ใช้ความโปร่งใสของใบรับรองได้
ตัวอย่างเช่น คุณอาจต้องการอนุญาตให้แอปเชื่อมต่อกับ
secure.example.com
โดยไม่ต้องใช้ความโปร่งใสของใบรับรอง
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">secure.example.com</domain> <certificateTransparency enabled="false"/> </domain-config> </network-security-config>
ClientHello ที่เข้ารหัส
หมายเหตุ: การรองรับ Encrypted Client Hello จะใช้ได้ตั้งแต่ Android 17 (ระดับ API 37) ขึ้นไปเท่านั้น และกำหนดให้ไลบรารีเครือข่ายของแอปต้องรองรับ ECH การกำหนดค่าที่ระบุ ที่นี่จะมีผลก็ต่อเมื่อไลบรารีเครือข่ายใช้ ECH
ClientHello ที่เข้ารหัส (ECH, RFC 9849) คือส่วนขยายโปรโตคอล TLS ที่ออกแบบมาเพื่อเพิ่มความเป็นส่วนตัวของการเชื่อมต่อที่ปลอดภัย โดยจะเข้ารหัสส่วนที่มีความละเอียดอ่อน ของการแฮนด์เชค TLS เริ่มต้น ซึ่งส่วนที่สำคัญที่สุดคือฟิลด์การระบุชื่อเซิร์ฟเวอร์ (SNI)
การเข้ารหัส SNI ด้วย ECH จะช่วยป้องกันไม่ให้ตัวกลางในเครือข่ายสังเกตชื่อโดเมนที่เฉพาะเจาะจงซึ่งไคลเอ็นต์พยายามเชื่อมต่อ ซึ่งจะช่วยป้องกันไม่ให้มีการ ลายนิ้วมือหรือการตรวจสอบผู้ใช้ตามโดเมนที่เข้าชม ซึ่งจะช่วยลดการรั่วไหลของความเป็นส่วนตัวที่สำคัญ ซึ่งมีอยู่ในแฮนด์เชค TLS มาตรฐาน
ลักษณะการทำงานเริ่มต้นของ Encrypted Client Hello จะขึ้นอยู่กับระดับ API ดังนี้
- ตั้งแต่ Android 17 (ระดับ API 37) เป็นต้นไป ระบบจะใช้ ECH ในโหมด "Opportunistic" โดยค่าเริ่มต้น แอปสามารถเลือกไม่ใช้ฟีเจอร์หรือแก้ไขลักษณะการทำงานของฟีเจอร์ได้ทั้งทั่วโลกหรือต่อโดเมน
- ใน Android 16 (ระดับ API 36) และต่ำกว่า ECH จะไม่พร้อมใช้งาน
เลือกไม่ใช้ Encrypted Client Hello
คุณเลือกไม่ใช้ฟีเจอร์นี้ได้โดยการปิดใช้ ตัวอย่างเช่น หากต้องการปิดใช้ ECH
เมื่อเชื่อมต่อกับ disable-ech.example.com เท่านั้น แต่เปิดใช้ ECH ไว้สำหรับ
โดเมนอื่นๆ ทั้งหมด คุณสามารถใช้การกำหนดค่าต่อไปนี้
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <domainEncryption mode="enabled"/> </base-config> <domain-config> <domain includeSubdomains="true">disable-ech.example.com</domain> <domainEncryption mode="disabled"/> </domain-config> </network-security-config>
การรับส่งข้อมูลข้อความที่โอนหรือจัดเก็บได้โดยไม่ต้องเข้ารหัส
นักพัฒนาแอปสามารถเลือกใช้หรือไม่ใช้การรับส่งข้อมูลที่ไม่มีการเข้ารหัส (ใช้โปรโตคอล HTTP ที่ไม่มีการเข้ารหัสแทน
HTTPS) สำหรับแอปพลิเคชันของตนได้ ดูรายละเอียดเพิ่มเติมได้ที่
NetworkSecurityPolicy.isCleartextTrafficPermitted()
ลักษณะการทำงานเริ่มต้นของการรับส่งข้อมูลข้อความธรรมดาจะขึ้นอยู่กับระดับ API ดังนี้
- ใน Android 8.1 (ระดับ API 27) ขึ้นไป ระบบจะเปิดใช้การรองรับข้อความธรรมดาโดยค่าเริ่มต้น แอปพลิเคชันสามารถเลือกไม่ใช้การรับส่งข้อมูลที่ไม่มีการเข้ารหัสเพื่อเพิ่มความปลอดภัย
- ตั้งแต่ Android 9 (API ระดับ 28) เป็นต้นไป ระบบจะปิดใช้การรองรับข้อความธรรมดาโดยค่าเริ่มต้น แอปพลิเคชันที่ต้องใช้การรับส่งข้อมูลแบบข้อความธรรมดา (Cleartext) สามารถเลือกใช้การรับส่งข้อมูลแบบข้อความธรรมดาได้
เลือกไม่ใช้การรับส่งข้อมูลข้อความธรรมดา
หมายเหตุ: คำแนะนำในส่วนนี้ใช้ได้กับแอปที่กำหนดเป้าหมายเป็น Android 8.1 (API ระดับ 27) หรือต่ำกว่าเท่านั้น
หากต้องการให้แอปเชื่อมต่อกับปลายทางโดยใช้เฉพาะการเชื่อมต่อที่ปลอดภัย คุณสามารถ เลือกไม่รองรับการรับส่งข้อมูลแบบข้อความธรรมดา (Cleartext) ไปยังปลายทางเหล่านั้นได้ ตัวเลือกนี้ช่วยป้องกัน การถดถอยโดยไม่ตั้งใจในแอปเนื่องจากการเปลี่ยนแปลง URL ที่ได้รับจากแหล่งที่มาภายนอก เช่น เซิร์ฟเวอร์แบ็กเอนด์
เช่น คุณอาจต้องการให้แอปตรวจสอบว่าการเชื่อมต่อกับ
secure.example.com
ดำเนินการผ่าน HTTPS เสมอเพื่อปกป้องการรับส่งข้อมูลที่ละเอียดอ่อนจากเครือข่ายที่เป็นอันตราย
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
เลือกใช้การรับส่งข้อมูลแบบข้อความธรรมดา
หมายเหตุ: คำแนะนำในส่วนนี้ใช้กับแอปที่กำหนดเป้าหมายเป็น Android 9 (API ระดับ 28) ขึ้นไปเท่านั้น
หากแอปต้องเชื่อมต่อกับปลายทางโดยใช้การรับส่งข้อมูลที่ไม่ได้เข้ารหัส (HTTP) คุณสามารถเลือกใช้ การรองรับข้อความที่ไม่ได้เข้ารหัสไปยังปลายทางเหล่านั้นได้
เช่น คุณอาจต้องการอนุญาตให้แอปสร้างการเชื่อมต่อที่ไม่ปลอดภัยกับ insecure.example.com
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">insecure.example.com</domain> </domain-config> </network-security-config>
หากแอปต้องเลือกใช้การเข้าชมแบบข้อความธรรมดา (Cleartext) ไปยังโดเมนใดก็ตาม ให้ตั้งค่า
cleartextTrafficPermitted="true" ใน base-config โปรดทราบว่าควรหลีกเลี่ยงการกำหนดค่าที่ไม่ปลอดภัยนี้
ทุกครั้งที่ทำได้
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> </base-config> </network-security-config>
ปักหมุดใบรับรอง
โดยปกติแล้ว แอปจะเชื่อถือ CA ทั้งหมดที่ติดตั้งไว้ล่วงหน้า หาก CA เหล่านี้ออกใบรับรองที่ฉ้อโกง แอปจะมีความเสี่ยงจากผู้โจมตีที่อยู่บนเส้นทาง บางแอปเลือกที่จะจำกัด ชุดใบรับรองที่ยอมรับโดยจำกัดชุด CA ที่เชื่อถือหรือโดยการปักหมุดใบรับรอง
การปักหมุดใบรับรองทำได้โดยการระบุชุดใบรับรองตามแฮชของคีย์สาธารณะ
(SubjectPublicKeyInfo ของใบรับรอง X.509) จากนั้นเชนใบรับรองจะ
ใช้ได้ก็ต่อเมื่อเชนใบรับรองมีคีย์สาธารณะที่ปักหมุดไว้อย่างน้อย 1 รายการ
โปรดทราบว่าเมื่อใช้การตรึงใบรับรอง คุณควรใส่คีย์สำรองไว้เสมอ เพื่อให้หากต้องเปลี่ยนไปใช้คีย์ใหม่หรือเปลี่ยน CA (เมื่อตรึงกับใบรับรอง CA หรือใบรับรองระดับกลางของ CA นั้น) การเชื่อมต่อของแอปจะไม่ได้รับผลกระทบ ไม่เช่นนั้น คุณต้องพุช การอัปเดตไปยังแอปเพื่อกู้คืนการเชื่อมต่อ
นอกจากนี้ คุณยังตั้งค่าเวลาหมดอายุสำหรับหมุดได้ด้วยหลังจากนั้นระบบจะไม่ปักหมุด ซึ่งจะช่วยป้องกันปัญหาการเชื่อมต่อในแอปที่ยังไม่ได้อัปเดต อย่างไรก็ตาม การตั้งค่าเวลาหมดอายุในพินอาจทำให้ผู้โจมตีข้ามใบรับรองที่ปักหมุดไว้ได้
ข้อมูลต่อไปนี้แสดงวิธีปักหมุดใบรับรองใน
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-- backup pin --> <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin> </pin-set> </domain-config> </network-security-config>
ลักษณะการทำงานของการรับค่าการกำหนดค่า
ค่าที่ไม่ได้ตั้งค่าในการกำหนดค่าที่เฉพาะเจาะจงจะได้รับการรับค่า ลักษณะการทำงานนี้ช่วยให้กำหนดค่าที่ซับซ้อนมากขึ้นได้ ในขณะที่ยังคงอ่านไฟล์การกำหนดค่าได้
เช่น ค่าที่ไม่ได้ตั้งไว้ใน domain-config จะนำมาจาก domain-config ระดับบน หากมีการซ้อนกัน หรือจาก base-config หากไม่มีการซ้อนกัน ค่า
ที่ไม่ได้ตั้งค่าใน base-config จะใช้ค่าเริ่มต้นของแพลตฟอร์ม
ตัวอย่างเช่น พิจารณากรณีที่การเชื่อมต่อทั้งหมดกับโดเมนย่อยของ
example.com ต้องใช้ชุด CA ที่กำหนดเอง นอกจากนี้ ยังอนุญาตการรับส่งข้อมูลแบบข้อความธรรมดา (Cleartext) ไปยังโดเมนเหล่านี้ยกเว้นเมื่อเชื่อมต่อกับ secure.example.com
การซ้อนการกำหนดค่าสำหรับ secure.example.com ไว้ในการกำหนดค่าสำหรับ
example.com ทำให้ไม่จำเป็นต้องทำซ้ำ trust-anchors
ข้อความที่ตัดตอนมาด้านล่างแสดงลักษณะการซ้อนกันใน
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </domain-config> </network-security-config>
การกำหนดค่า localhost
โดยทั่วไปแล้วไม่จำเป็นต้องบังคับใช้ฟีเจอร์ความปลอดภัยของเครือข่ายสำหรับการเชื่อมต่อ localhost เช่น ไม่ค่อยจำเป็นต้องใช้ความโปร่งใสของใบรับรองสำหรับการเชื่อมต่อ localhost
ตั้งแต่ Android 17 (ระดับ API 37) ขึ้นไป หากไม่ได้กำหนดค่าสำหรับ localhost ระบบจะรวมการกำหนดค่าโดยนัย โดยค่าเริ่มต้น การกำหนดค่านี้จะทำสิ่งต่อไปนี้
- อนุญาตการรับส่งข้อมูลแบบข้อความธรรมดา (Cleartext)
- ไม่บังคับใช้การตรวจสอบความโปร่งใสของใบรับรอง (CT)
- ไม่บังคับใช้การปักหมุดใบรับรอง
- มอบสิทธิ์ให้
<base-config>สำหรับจุดยึดความน่าเชื่อถือ
ระบบจะถือว่าการกำหนดค่าเป็นการกำหนดเป้าหมาย localhost หากโดเมนมีลักษณะดังนี้
localhostip6-localhostหรือ-
ที่อยู่ IP ที่เป็นตัวเลขและ
InetAddress.isLoopback()คือtrue(เช่น127.0.0.1หรือ[::1])
รูปแบบไฟล์การกำหนดค่า
ฟีเจอร์การกำหนดค่าความปลอดภัยเครือข่ายใช้รูปแบบไฟล์ XML โครงสร้างโดยรวมของไฟล์แสดงอยู่ในตัวอย่างโค้ดต่อไปนี้
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </base-config> <domain-config> <domain>android.com</domain> ... <trust-anchors> <certificates src="..."/> ... </trust-anchors> <pin-set> <pin digest="...">...</pin> ... </pin-set> </domain-config> ... <debug-overrides> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </debug-overrides> </network-security-config>
ส่วนต่อไปนี้จะอธิบายไวยากรณ์และรายละเอียดอื่นๆ ของรูปแบบไฟล์
<network-security-config>
- อาจมีข้อมูลต่อไปนี้
-
0 หรือ 1 ของ
<base-config>
<domain-config>
จำนวนเท่าใดก็ได้ 0 หรือ 1 ของ<debug-overrides>
<base-config>
- ไวยากรณ์:
<base-config cleartextTrafficPermitted=["true" | "false"]> ... </base-config>
- อาจมีข้อมูลต่อไปนี้
-
<trust-anchors><certificateTransparency><domainEncryption> - description:
-
การกำหนดค่าเริ่มต้นที่ใช้โดยการเชื่อมต่อทั้งหมดซึ่งมีปลายทางที่ไม่ได้ครอบคลุมโดย
domain-configค่าที่ไม่ได้ตั้งค่าจะใช้ค่าเริ่มต้นของแพลตฟอร์ม
การกำหนดค่าเริ่มต้นสำหรับแอปที่กำหนดเป้าหมายเป็น Android 9 (ระดับ API 28) ขึ้นไปมีดังนี้
<base-config cleartextTrafficPermitted="false"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
การกำหนดค่าเริ่มต้นสำหรับแอปที่กำหนดเป้าหมายเป็น Android 7.0 (ระดับ API 24) ถึง Android 8.1 (ระดับ API 27) มีดังนี้
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
การกำหนดค่าเริ่มต้นสำหรับแอปที่กำหนดเป้าหมายเป็น Android 6.0 (ระดับ API 23) และต่ำกว่ามีดังนี้
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
<domain-config>
- ไวยากรณ์:
-
<domain-config cleartextTrafficPermitted=["true" | "false"]> ... </domain-config>
- อาจมีข้อมูลต่อไปนี้
-
<domain>
0 หรือ 1<certificateTransparency>
0 หรือ 1<trust-anchors>
0 หรือ 1<pin-set>
0 หรือ 1<domainEncryption>
<domain-config> - description:
-
การกำหนดค่าที่ใช้สำหรับการเชื่อมต่อกับปลายทางที่เฉพาะเจาะจงตามที่กำหนดโดยองค์ประกอบ
domainโปรดทราบว่าหากองค์ประกอบ
domain-configหลายรายการครอบคลุมปลายทาง ระบบจะใช้การกำหนดค่าที่มีกฎโดเมนที่ตรงกันที่เจาะจงที่สุด (ยาวที่สุด)
<โดเมน>
- ไวยากรณ์:
-
<domain includeSubdomains=["true" | "false"]>example.com</domain>
- แอตทริบิวต์
-
-
includeSubdomains -
หากเป็น
"true"แสดงว่ากฎโดเมนนี้ตรงกับโดเมนและโดเมนย่อยทั้งหมด รวมถึงโดเมนย่อยของโดเมนย่อย มิเช่นนั้น กฎจะมีผลกับการทำงานแบบตรงทั้งหมดเท่านั้น
-
<certificateTransparency>
- ไวยากรณ์:
-
<certificateTransparency enabled=["true" | "false"]/>
- description:
-
หาก
trueแอปจะใช้บันทึกความโปร่งใสของใบรับรองเพื่อตรวจสอบ ใบรับรอง เมื่อแอปใช้ใบรับรองของตัวเอง (หรือที่เก็บของผู้ใช้) มีแนวโน้มว่า ใบรับรองจะไม่ใช่แบบสาธารณะและตรวจสอบไม่ได้โดยใช้ความโปร่งใสของใบรับรอง โดยค่าเริ่มต้น ระบบจะปิดใช้การยืนยันสำหรับกรณีเหล่านี้ คุณยังคงบังคับให้มีการยืนยันได้โดยใช้<certificateTransparency enabled="true"/>ในการกำหนดค่าโดเมน สำหรับการประเมินแต่ละครั้ง<domain-config>จะเป็นไปตามลำดับต่อไปนี้- หากเปิดใช้
certificateTransparencyให้เปิดใช้การยืนยัน -
หาก
<trust-anchors>เป็น"user"หรืออยู่ในบรรทัด (เช่น"@raw/cert.pem") ให้ปิดใช้ การยืนยัน - หรือใช้การกำหนดค่าที่รับช่วง
- หากเปิดใช้
<domainEncryption>
- ไวยากรณ์:
-
<domainEncryption mode=["enabled" | "opportunistic" | "disabled"]/>
- description:
-
ควบคุมลักษณะการทำงานของ Encrypted Client Hello (ECH)
สำหรับการเชื่อมต่อกับโดเมนที่ระบุ
หมายเหตุ: องค์ประกอบ
domainEncryptionขึ้นอยู่กับว่าไลบรารีเครือข่ายของแอป รองรับ ECH หรือไม่ ลักษณะการทำงานที่ระบุจะมีผล หากไลบรารีเครือข่ายใช้ ECH แอปไม่ควรจัดการการกำหนดค่า ECH ด้วยตนเอง แต่ควรใช้ไลบรารีเครือข่ายแทนเมื่อสร้างแฮนด์เชค TLSแอตทริบิวต์
modeอาจเป็นค่าใดค่าหนึ่งต่อไปนี้enabled: บังคับใช้ ECH ในการเชื่อมต่อเมื่อมีการกำหนดค่า ECH เมื่อสร้างแฮนด์เชค TLS และเปิดใช้ ECH GREASE ในกรณีอื่นๆopportunistic: ใช้ ECH ในการเชื่อมต่อเมื่อมีการกำหนดค่า ECH เมื่อสร้างแฮนด์เชค TLS หากการเชื่อมต่อล้มเหลวหรือไม่ได้ระบุการกำหนดค่า ให้กลับไปใช้ ClientHello ของ TLS มาตรฐานที่ไม่ได้เข้ารหัส โหมดนี้ไม่ได้เปิดใช้ ECH GREASEdisabled: อย่าพยายามใช้ ECH หรือ ECH GREASE ในการเชื่อมต่อใดๆ
หากไม่ได้ระบุไว้ ค่าเริ่มต้น
modeคือ"opportunistic"
<debug-overrides>
- ไวยากรณ์:
-
<debug-overrides> ... </debug-overrides> - อาจมีข้อมูลต่อไปนี้
-
0 หรือ 1
<trust-anchors> - description:
-
การลบล้างที่จะใช้เมื่อ
android:debuggable เป็น
"true"ซึ่งโดยปกติแล้วจะเป็นกรณีสำหรับบิลด์ที่ไม่ใช่รุ่นที่เผยแพร่ซึ่งสร้างโดย IDE และ เครื่องมือบิลด์ ระบบจะเพิ่ม Trust Anchor ที่ระบุในdebug-overridesลงในการกำหนดค่าอื่นๆ ทั้งหมด และจะไม่ทำการตรึงใบรับรองเมื่อห่วงโซ่ใบรับรองของเซิร์ฟเวอร์ ใช้ Trust Anchor ที่ใช้สำหรับการแก้ไขข้อบกพร่องเท่านั้นรายการใดรายการหนึ่ง หาก android:debuggable เป็น"false"ระบบจะไม่สนใจส่วนนี้โดยสิ้นเชิง
<trust-anchors>
- ไวยากรณ์:
-
<trust-anchors> ... </trust-anchors>
- อาจมีข้อมูลต่อไปนี้
-
<certificates>จำนวนเท่าใดก็ได้ - description:
- ชุดจุดยึดความน่าเชื่อถือสำหรับการเชื่อมต่อที่ปลอดภัย
<certificates>
- ไวยากรณ์:
-
<certificates src=["system" | "user" | "raw resource"] overridePins=["true" | "false"] />
- description:
- ชุดใบรับรอง X.509 สำหรับองค์ประกอบ
trust-anchors - แอตทริบิวต์
-
src-
แหล่งที่มาของใบรับรอง CA ใบรับรองแต่ละรายการอาจเป็นอย่างใดอย่างหนึ่งต่อไปนี้
- รหัสทรัพยากรดิบที่ชี้ไปยังไฟล์ที่มีใบรับรอง X.509 ใบรับรอง ต้องเข้ารหัสในรูปแบบ DER หรือ PEM ในกรณีของใบรับรอง PEM ไฟล์ ต้องไม่มีข้อมูลที่ไม่ใช่ PEM เพิ่มเติม เช่น ความคิดเห็น
"system"สำหรับใบรับรอง CA ของระบบที่ติดตั้งไว้ล่วงหน้า"user"สำหรับใบรับรอง CA ที่ผู้ใช้เพิ่มไว้
overridePins-
ระบุว่า CA จากแหล่งที่มานี้จะข้ามการปักหมุดใบรับรองหรือไม่ หาก
"true"ระบบจะไม่ปักหมุดเชนใบรับรองที่ ลงนามโดย CA รายการใดรายการหนึ่งจากแหล่งที่มานี้ ซึ่งอาจมีประโยชน์สำหรับการแก้ไขข้อบกพร่องของ CA หรือสำหรับการ ทดสอบการโจมตีแบบแทรกกลางในการรับส่งข้อมูลที่ปลอดภัยของแอปค่าเริ่มต้นคือ
"false"เว้นแต่จะระบุไว้ในองค์ประกอบdebug-overridesซึ่งในกรณีนี้ค่าเริ่มต้นจะเป็น"true"
<pin-set>
- ไวยากรณ์:
-
<pin-set expiration="date"> ... </pin-set> - อาจมีข้อมูลต่อไปนี้
-
<pin>จำนวนเท่าใดก็ได้ - description:
-
ชุดการปักหมุดคีย์สาธารณะ หากต้องการให้การเชื่อมต่อที่ปลอดภัยเป็นที่เชื่อถือ คีย์สาธารณะอย่างน้อย 1 รายการใน
ห่วงโซ่ความน่าเชื่อถือต้องอยู่ในชุดพิน ดูรูปแบบของหมุดได้ที่
<pin> - แอตทริบิวต์
-
-
expiration -
วันที่ในรูปแบบ
yyyy-MM-ddที่ PIN หมดอายุ ซึ่งจะปิดใช้การปักหมุด หากไม่ได้ตั้งค่าแอตทริบิวต์นี้ PIN จะไม่มีวันหมดอายุการหมดอายุจะช่วยป้องกันปัญหาการเชื่อมต่อในแอปที่ไม่ได้รับการอัปเดตชุดพิน เช่น เมื่อผู้ใช้ปิดใช้การอัปเดตแอป
-
<pin>
- ไวยากรณ์:
-
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>
- แอตทริบิวต์
-
-
digest -
อัลกอริทึมสำหรับไดเจสต์ที่ใช้สร้างพิน ปัจจุบันรองรับเฉพาะ
"SHA-256"
-