Android APK签名 与 jks文件
Android APK签名
一、核心概念
APK签名是Android应用发布的核心安全机制,用于验证应用的完整性和来源真实性。它确保APK在发布后不被篡改,并建立开发者身份的可信链。
二、核心目的
- 完整性验证 - 确保APK在签名后未被修改
- 身份认证 - 确认应用来自特定开发者
- 版本升级控制 - 防止恶意应用覆盖合法应用
- 权限共享 - 允许相同签名的应用共享数据
三、技术架构
1. 密钥和证书体系
# 典型的密钥生成
keytool -genkeypair -v \
-keystore my-release-key.jks \
-keyalg RSA -keysize 4096 \
-validity 10000 \
-alias my-alias \
-sigalg SHA256withRSA \
-dname "CN=Developer Name, OU=Unit, O=Company, L=City, ST=State, C=CN"
关键参数:
- 密钥库(Keystore): JKS(Java KeyStore)或PKCS12格式
- 密钥算法: RSA(推荐4096位)或ECC
- 签名算法: SHA256withRSA, SHA256withECDSA
- 有效期: Google Play要求至少2033年10月22日后到期
2. 签名方案演进
V1签名(JAR签名)
# 基于JAR文件的MANIFEST.MF签名
jarsigner -verbose -sigalg SHA256withRSA \
-digestalg SHA-256 \
-keystore my-release-key.jks \
app.apk my-alias
技术细节:
- 在META-INF/目录创建:
- MANIFEST.MF(文件哈希列表)
- CERT.SF(清单签名文件)
- CERT.RSA(证书和签名)
- 不保护APK整体结构
V2签名(APK签名方案v2)
# 在APK中插入签名块
+-----------------------------------+
| ZIP entries (before Central Directory) |
+-----------------------------------+
| APK Signing Block (v2) | ← 新增签名块
+-----------------------------------+
| Central Directory |
+-----------------------------------+
| End of Central Directory |
+-----------------------------------+
关键技术:
- 计算整个APK(除签名块)的哈希树
- 防篡改保护包括ZIP元数据
- 支持APK分块对齐优化
- 更快的验证速度
V3签名(APK签名方案v3)
- 支持密钥轮换,保持升级连续性
- 添加额外的证明块
- 向后兼容V2
V4签名(基于fs-verity)
- 为增量APK安装设计
- 生成整个APK的Merkle树
- 文件系统级完整性验证
四、签名生成流程
详细步骤:
- 计算哈希 - 对每个文件计算摘要
- 生成清单 - 创建MANIFEST.MF记录所有摘要
- 签名清单 - 用私钥签署清单文件
- 构建签名块 - 组织证书和签名
- 插入APK - 将签名数据嵌入APK结构
五、验证流程
系统验证过程:
+-------------------+ +-------------------+ +-------------------+
| 启动验证请求 | → | 提取证书链 | → | 验证签名完整性 |
+-------------------+ +-------------------+ +-------------------+
↓ ↓ ↓
+-------------------+ +-------------------+ +-------------------+
| 检查密钥有效期 | → | 验证证书链信任 | → | 比较APK哈希值 |
+-------------------+ +-------------------+ +-------------------+
jks文件
一、JKS文件的本质
JKS(Java KeyStore)文件是一个容器,它包含了:
- 私钥(Private Key)- 用于签名
- 公钥证书(Public Key Certificate)- 包含公钥,用于验证
- 证书链(Certificate Chain)- 可选,包含CA证书
- 元数据 - 如别名、有效期等
# 查看JKS文件内容
keytool -list -v -keystore my-release-key.jks
输出示例:
密钥库类型: JKS
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: my-alias
创建日期: 2023-1-1
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=John Doe, OU=Android, O=Google, L=Mountain View, ST=California, C=US
发布者: CN=John Doe, OU=Android, O=Google, L=Mountain View, ST=California, C=US
序列号: 123456
有效期: Jan 1 00:00:00 2023 GMT 至: Jan 1 00:00:00 2033 GMT
证书指纹:
SHA1: 12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78
SHA256: AB:CD:EF:...
签名算法名称: SHA256withRSA
主体公共密钥算法: 4096位RSA密钥
二、JKS的内部结构
my-release-key.jks (密钥库文件)
├── 存储密码: 保护整个密钥库
└── 条目1: "my-alias"
├── 私钥 (encrypted) # 🔐 绝密!用于签名
├── 密钥密码 # 保护私钥
└── 公钥证书 # 公开的,用于验证
├── 公钥
├── 主体信息
├── 有效期
└── 数字签名
三、为什么这样设计?
1. 安全性考虑
- 私钥永远不离开JKS文件:私钥在JKS中是加密存储的
- 证书可安全分发:证书只包含公钥,可以公开
- 双重密码保护:
- 密钥库密码:访问整个JKS
- 密钥密码:使用特定私钥
2. 工作流程
开发者机器:
JKS文件(私钥+证书) → 签名APK → 发布到商店
↓
私钥保留本地
↓
用户设备:
从APK提取证书(公钥) → 验证签名
四、JKS文件的保护层级
密码保护层级:
JKS文件
├── 外层:存储密码(保护整个文件)
│ └── 别名1
│ ├── 私钥 → 用密钥密码A加密
│ └── 证书(公钥)→ 明文
│
├── 别名2
│ ├── 私钥 → 用密钥密码B加密
│ └── 证书(公钥)→ 明文
│
└── 别名3
├── 私钥 → 用密钥密码C加密
└── 证书(公钥)→ 明文
留下评论