การยืนยันการขึ้นต่อกัน

ไลบรารี Gradle ที่ถูกบุกรุกเป็นความเสี่ยงด้านความปลอดภัย ผู้ไม่ประสงค์ดีอาจแทรกพึ่งพาที่แก้ไขแล้วลงในกระบวนการสร้างได้ เช่น ผ่านการโจมตีแบบคนกลางระหว่างการแก้ไขพึ่งพา

หากองค์ประกอบที่จำเป็นต่อการสร้าง (ไลบรารี) ถูกบุกรุก อาจส่งผลต่อวิธีการทำงานของแอปพลิเคชันในอุปกรณ์ หากมีการบุกรุกทรัพยากรของพลีแคน สิ่งนั้นอาจเปลี่ยนวิธีการทำงานของบิลด์ หรือแม้แต่เรียกใช้คำสั่งภายนอกในเครื่องที่ใช้สร้าง

คุณสามารถลดปัญหานี้ได้ด้วยการเปิดใช้การยืนยันทรัพยากร Dependency ในบิลด์

Checksum และลายเซ็นของคลัง

ผู้เขียนไลบรารีสามารถระบุข้อมูลเมตา 2 รายการที่จะช่วยยืนยันความถูกต้องของไลบรารีที่คุณดาวน์โหลด คุณจะกำหนดไฟล์ชื่อ gradle/verification-metadata.xml เพื่อระบุค่าที่คุณอนุมัติได้ โดยอาจมีข้อมูลต่อไปนี้

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

    ข้อเสียคือ เนื่องจากระบบจะคํานวณการตรวจสอบผลรวมจากอาร์ติแฟกต์ การตรวจสอบผลรวมจึงเปลี่ยนแปลงไปพร้อมกับทุกรุ่น ซึ่งหมายความว่าคุณต้องอัปเดต gradle/verification-metadata.xml ทุกครั้งที่อัปเกรด

  • ลายเซ็น - อนุญาตให้ผู้ใช้ทรัพยากร Dependency ระบุคีย์สาธารณะสำหรับอาร์ติแฟกต์หนึ่งๆ เพื่อตรวจสอบว่าอาร์ติแฟกต์นี้สร้างขึ้นและลงนามโดยผู้เขียนไลบรารีซึ่งเป็นเจ้าของที่ตรวจสอบสิทธิ์แล้วของคีย์สาธารณะนั้น การดำเนินการนี้จะทำให้ผู้เขียนคลังงานต้องทำงานมากขึ้น แต่ตราบใดที่คีย์ส่วนตัวของผู้เขียนไม่ถูกบุกรุก ลายเซ็นจะบอกคุณว่าคลังงานนั้นถูกต้อง

    หากผู้เขียนคลังเซ็นอาร์ติแฟกต์แต่ละเวอร์ชันด้วยคีย์เดียวกัน คุณไม่จำเป็นต้องอัปเดต gradle/verification-metadata.xml เมื่ออัปเกรด

เปิดใช้การยืนยันทรัพยากร Dependency

การยืนยันการพึ่งพา Gradle จะเปรียบเทียบการตรวจสอบและลายเซ็นระหว่างการสร้าง

สร้างไฟล์ gradle/verification-metadata.xml ที่มีข้อมูลต่อไปนี้

<?xml version="1.0" encoding="UTF-8"?>
<verification-metadata
    xmlns="https://schema.gradle.org/dependency-verification"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd">
    <configuration>
        <!-- verify .pom and .module files -->
        <verify-metadata>true</verify-metadata>
        <!-- verify .asc PGP files that come with the artifacts -->
        <verify-signatures>true</verify-signatures>
        <!-- use human readable keyring format -->
        <keyring-format>armored</keyring-format>
        <!-- read keys in a local file, fewer requests to network -->
        <key-servers enabled="false">
            <key-server uri="https://keyserver.ubuntu.com"/>
            <key-server uri="https://keys.openpgp.org"/>
        </key-servers>
    </configuration>
    <components>
    </components>
</verification-metadata>

ข้อมูลนี้ใช้เป็นจุดเริ่มต้นและจะอัปเดตในเร็วๆ นี้

เรียกใช้ ./gradlew assembleDebug เพื่อดูว่าการเปลี่ยนแปลงนี้ส่งผลต่อบิลด์อย่างไร คุณจะเห็นข้อความ เช่น

* What went wrong:
Error resolving plugin [id: 'com.android.application', version: '8.7.3', apply: false]
> Dependency verification failed for configuration 'detachedConfiguration1'
  One artifact failed verification: com.android.application.gradle.plugin-8.7.3.pom ...
  This can indicate that a dependency has been compromised ...
  
  Open this report for more details: .../dependency-verification-report.html

Gradle แจ้งว่าคุณกําลังดึงข้อมูลเวอร์ชันของ Dependency ที่คุณไม่ได้อนุมัติอย่างชัดเจน

บูตสตาร์ทข้อมูลการตรวจสอบและลายเซ็น

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

สร้างข้อมูลเมตาเริ่มต้นโดยเรียกใช้

./gradlew --write-verification-metadata pgp,sha256 --export-keys help

คำสั่งนี้จะบอกให้ Gradle สร้างรายการคีย์ PGP และการตรวจสอบผลรวมสำรองสำหรับไลบรารีทั้งหมดที่ใช้ในโปรเจ็กต์นี้ คุณจะเห็นการเปลี่ยนแปลงใน verification-metadata.xml ที่มีรายการต่างๆ เช่น

<trusted-key id="8461EFA0E74ABAE010DE66994EB27DB2A3B88B8B">
    <trusting group="androidx.activity"/>
</trusted-key>

ซึ่งจะบอก Gradle ว่าหากเห็นการพึ่งพาจากกลุ่ม Maven androidx.activity ระบบจะตรวจสอบว่าไฟล์ .asc ที่มาพร้อมกับไฟล์นั้น (ลายเซ็นที่จัดเก็บในที่เก็บ) ตรงกับคีย์นั้น

การเริ่มต้นระบบจะสร้าง gradle/verification-keyring.keys ที่มีคีย์ PGP สาธารณะซึ่งบิลด์ของคุณใช้ด้วย ตรวจสอบไฟล์ทั้ง 2 ไฟล์นี้ในระบบการติดตามเวอร์ชัน การเปลี่ยนแปลงในอนาคตที่แก้ไข verification-metadata.xml หรือ verification-keyring.keys ควรได้รับการตรวจสอบอย่างละเอียด

นำเวอร์ชันออกจากคีย์ที่เชื่อถือได้

คีย์การรับรองไม่ค่อยเปลี่ยนแปลงระหว่างรุ่นต่างๆ ของไลบรารี ข้อมูลที่สร้างขึ้นในไฟล์ gradle/verification-metadata.xml มีรายละเอียดเวอร์ชัน ซึ่งหมายความว่าคุณจะต้องเพิ่มข้อมูลสำคัญสำหรับเวอร์ชันใหม่ของข้อกำหนดใหม่แต่ละรายการอีกครั้ง

หากต้องการหลีกเลี่ยงปัญหานี้และระบุว่าคีย์มีผลกับคลังทุกเวอร์ชัน ให้นําข้อกําหนดเวอร์ชันออก

ในเครื่องมือแก้ไขของ Android Studio ให้ใช้แก้ไข > ค้นหา > แทนที่... ใช้นิพจน์ทั่วไปเพื่อแทนที่ข้อกำหนดเวอร์ชันทั้งหมดสำหรับคีย์ที่เชื่อถือ

  • จาก: <trusted-key(.*) version=\".*\"/>
  • ถึง: <trusted-key$1/>

การซิงค์ Android Studio

จนถึงตอนนี้ บิลด์บรรทัดคำสั่งของคุณใช้งานได้ แต่หากคุณพยายามซิงค์ใน Android Studio คุณจะเห็นข้อผิดพลาด เช่น

A build operation failed.
    Dependency verification failed for configuration ':app:detachedConfiguration3'
One artifact failed verification: gradle-8.10.2-src.zip (gradle:gradle:8.10.2) from repository Gradle distributions
If the artifacts are trustworthy, you will need to update the gradle/verification-metadata.xml file. For more on how to do this, please refer to https://docs.gradle.org/8.10.2/userguide/dependency_verification.html#sec:troubleshooting-verification in the Gradle documentation.

Android Studio ต้องการดาวน์โหลดแหล่งที่มาของ Gradle (พร้อมกับแหล่งที่มาและเอกสารอื่นๆ) วิธีที่ง่ายที่สุดในการแก้ไขนี้คือเชื่อถือแหล่งที่มาและ Javadoc ทั้งหมด เพิ่ม<trusted-artifacts>ในgradle/verification-metadata.xml

<verification-metadata ...>
   <configuration>
      <trusted-artifacts>
         <trust file=".*-javadoc[.]jar" regex="true"/>
         <trust file=".*-sources[.]jar" regex="true"/>
         <trust group="gradle" name="gradle"/>
      </trusted-artifacts>
      ...
  </configuration>
</verification-metadata>

ตอนนี้บิลด์จะทำงานอย่างถูกต้องจากบรรทัดคำสั่งและ Android Studio แล้ว