依赖安全性校验
源: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 dependencyCheckAnalyzeGradle Enterprise:
- 依赖可视化
- 安全扫描
- 合规报告