Skip to content

依赖安全性校验

源:Gradle 官方文档 - Dependency Verification

依赖验证通过校验和(checksum)和签名验证,确保下载的依赖未被篡改,防止供应链攻击。

依赖验证重要性

安全威胁

中间人攻击

  • 依赖在传输过程中被替换
  • 恶意代码注入

仓库入侵

  • Maven 仓库被攻击
  • 依赖被恶意替换

供应链攻击

  • 上游库被攻击
  • 传递依赖包含恶意代码

验证的作用

确保完整性

  • 依赖未被篡改
  • 下载的就是发布的

防止攻击

  • 阻止恶意依赖
  • 及时发现问题

合规要求

  • 满足安全审计
  • 符合企业规范

启用依赖验证

生成验证文件

bash
# 首次生成验证文件
./gradlew --write-verification-metadata sha256 help

# 也可以使用其他算法
./gradlew --write-verification-metadata sha512 help
./gradlew --write-verification-metadata md5,sha1 help

生成位置

gradle/
└── verification-metadata.xml

验证文件格式

xml
<?xml version="1.0" encoding="UTF-8"?>
<verification-metadata>
   <configuration>
      <verify-metadata>true</verify-metadata>
      <verify-signatures>false</verify-signatures>
   </configuration>
   <components>
      <component group="androidx.core" name="core-ktx" version="1.15.0">
         <artifact name="core-ktx-1.15.0.aar">
            <sha256 value="abc123..."/>
         </artifact>
      </component>
   </components>
</verification-metadata>

校验和验证

支持的算法

推荐算法

  • SHA-256(推荐)
  • SHA-512(更安全)

不推荐

  • MD5(不安全)
  • SHA-1(已弃用)

生成校验和

bash
# 生成 SHA-256
./gradlew --write-verification-metadata sha256 dependencies

# 生成多个算法
./gradlew --write-verification-metadata sha256,sha512 dependencies

验证流程

构建时自动验证

bash
./gradlew build

验证失败

Dependency verification failed for configuration ':compileClasspath'
One artifact failed verification: core-ktx-1.15.0.aar 
Expected sha256: abc123...
Actual sha256:   def456...

签名验证

启用签名验证

配置

xml
<verification-metadata>
   <configuration>
      <verify-metadata>true</verify-metadata>
      <verify-signatures>true</verify-signatures>
      <trusted-keys>
         <!-- 信任的公钥ID -->
         <trusted-key id="abc123..." group="androidx.core"/>
         <trusted-key id="def456..." group="com.squareup.okhttp3"/>
      </trusted-keys>
   </configuration>
</verification-metadata>

导出签名

bash
# 导出所有签名信息
./gradlew --write-verification-metadata pgp,sha256 dependencies

# 导出到密钥环
./gradlew --export-keys dependencies

密钥环位置

gradle/
└── verification-keyring.gpg

更新验证元数据

添加新依赖

bash
# 更新验证文件
./gradlew --write-verification-metadata sha256 dependencies

注意:会覆盖现有验证文件

增量更新

手动添加

xml
<component group="com.example" name="new-lib" version="1.0">
   <artifact name="new-lib-1.0.jar">
      <sha256 value="new-checksum"/>
   </artifact>
</component>

批量更新

bash
# 更新所有配置
./gradlew --write-verification-metadata sha256 allDependencies

信任策略

信任特定依赖

xml
<verification-metadata>
   <configuration>
      <trust>
         <!-- 信任特定组 -->
         <trust group="androidx.core"/>
         <trust group="org.jetbrains.kotlin" name="kotlin-stdlib"/>
      </trust>
   </configuration>
</verification-metadata>

忽略特定工件

xml
<verification-metadata>
   <configuration>
      <ignored-keys>
         <ignored-key id="abc123..." reason="测试密钥"/>
      </ignored-keys>
   </configuration>
</verification-metadata>

CI/CD 集成

GitHub Actions

yaml
name: Verify Dependencies

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup JDK
        uses: actions/setup-java@v3
        with:
          java-version: '17'
      
      - name: Verify Dependencies
        run: ./gradlew build --no-daemon
      
      - name: Check verification file
        run: |
          if ! git diff --exit-code gradle/verification-metadata.xml; then
            echo "Verification metadata has changed!"
            exit 1
          fi

自动更新验证

yaml
- name: Update Verification Metadata
  if: github.event_name == 'pull_request'
  run: ./gradlew --write-verification-metadata sha256 dependencies
  
- name: Commit Changes
  uses: stefanzweifel/git-auto-commit-action@v4
  with:
    commit_message: "Update dependency verification"
    file_pattern: gradle/verification-metadata.xml

实战案例

案例1:Android 项目

初始化

bash
./gradlew --write-verification-metadata sha256 dependencies

验证文件

xml
<verification-metadata>
   <configuration>
      <verify-metadata>true</verify-metadata>
      <verify-signatures>false</verify-signatures>
   </configuration>
   <components>
      <component group="androidx.core" name="core-ktx" version="1.15.0">
         <artifact name="core-ktx-1.15.0.aar">
            <sha256 value="..."/>
         </artifact>
      </component>
      <component group="com.squareup.retrofit2" name="retrofit" version="2.11.0">
         <artifact name="retrofit-2.11.0.jar">
            <sha256 value="..."/>
         </artifact>
      </component>
   </components>
</verification-metadata>

案例2:企业项目

启用签名验证

xml
<verification-metadata>
   <configuration>
      <verify-metadata>true</verify-metadata>
      <verify-signatures>true</verify-signatures>
      <trusted-keys>
         <trusted-key id="company-key-id" group="com.company"/>
      </trusted-keys>
      <trust>
         <trust group="com.company"/>
      </trust>
   </configuration>
</verification-metadata>

案例3:多模块项目

根项目

bash
# 生成所有模块的验证
./gradlew --write-verification-metadata sha256 allDependencies

共享验证文件

project/
└── gradle/
    └── verification-metadata.xml  # 所有模块共享

最佳实践

选择安全的算法

  • 使用 SHA-256 或 SHA-512
  • 避免 MD5 和 SHA-1

提交验证文件

gitignore
# .gitignore
# 不要忽略验证文件
# gradle/verification-metadata.xml
# gradle/verification-keyring.gpg

定期更新

  • 添加新依赖时更新
  • 升级依赖时更新
  • Code Review 时检查

CI 强制验证

  • 构建时自动验证
  • 验证失败阻止合并
  • 自动检测变更

文档化信任决策

xml
<trust group="com.example">
   <!-- 原因:内部库,已通过安全审计 -->
</trust>

使用签名验证

  • 为关键依赖启用
  • 维护信任的密钥列表
  • 定期审查

常见问题

验证失败

问题:依赖验证失败

原因

  • 依赖已更新
  • 校验和不匹配
  • 依赖被篡改

解决

bash
# 检查依赖
./gradlew dependencies

# 重新生成验证
./gradlew --write-verification-metadata sha256 dependencies

性能影响

问题:启用验证后构建变慢

原因:需要计算和验证校验和

优化

  • 使用构建缓存
  • 仅验证关键依赖
  • 使用更快的算法(SHA-256)

密钥管理

问题:如何管理GPG密钥

建议

  • 导出密钥环到项目
  • 提交到版本控制
  • 定期更新

安全建议

启用验证

  • 所有生产项目
  • 公开发布的库
  • 企业应用

使用多层验证

  • 校验和 + 签名
  • 多个算法
  • 自动 + 人工审查

监控依赖变更

  • 订阅安全公告
  • 使用漏洞扫描工具
  • 定期审计

应急响应

  • 制定应急计划
  • 快速回滚机制
  • 通知流程

工具支持

OWASP Dependency-Check

kotlin
plugins {
    id("org.owasp.dependencycheck") version "9.0.0"
}

dependencyCheck {
    failBuildOnCVSS = 7.0f
}
bash
./gradlew dependencyCheckAnalyze

Gradle Enterprise

  • 依赖可视化
  • 安全扫描
  • 合规报告