signapk流程分析
来源:互联网 发布:如何办网络授权书 编辑:程序博客网 时间:2024/06/16 05:39
一点笔记
转载请注明出处
1. 对jar包中的各文件进行sha1hash,生成manifest对象;
除(
META-INF/MANIFEST.MF
META-INF/CERT.SF
META-INF/CERT.RSA
META-INF/com/android/otacert
"^META-INF/(.*)[.](SF|RSA|DSA)$"
)外
2. 将manifest对象中描述的各文件copy到新jar包中;
3. 如果-w整包签,则将 证书.x509.pem 复制到 META-INF/com/android/otacert;
并在manifest对象中增加META-INF/com/android/otacert的SHA1摘要;
4. 将manifest对象写入新jar包中META-INF/MANIFEST.MF文件;
5. 生成签名文件META-INF/CERT.SF;
内容生成方式:
对manifest中(每一项文件名称、sha1摘要)做sha1摘要, 生成新的Manifest对象
for (entry : OriManifest) {
SHA1(
"Name: entryName\r\n" ## e.g.:(Name: res\xml\xx.xml\r\n)
"SHA1-Digest=ORI-SHA1-Digest\r\n" ## "SHA1-Digest=tIoIjlV7AhAroOM3aDWl+6FaX+Q=\r\n"
"\r\n"
)
}
6. 生成META-INF/CERT.RSA;
PKCS#7格式签名/加密信息:(对CERT.SF进行SHA1withRSA,并将证书.pem附在其中);
7. 如果-w整包签,则在jar/zip文件
找到'End of central directory signature'
(一般zip如果无Comment length时,EOCD标记距尾部22Bytes)
[End of central directory record]格式
Offset Bytes Description[18]
0 4End of central directory signature | 核心目录结束标记(0x06054b50)
4 2Number of this disk | 当前磁盘编号
6 2Disk where central directory starts | 核心目录开始位置的磁盘编号
8 2Number of central directory records on this disk | 该磁盘上所记录的核心目录数量
10 2Total number of central directory records | 核心目录结构总数
12 4Size of central directory (bytes) | 核心目录的大小
16 4Offset of start of central directory,
relative to start of archive | 核心目录开始位置相对于archive开始的位移
20 2Comment length (n)注释长度
22 nComment注释内容
在其后写入Archive Comment:
--------------------------------------------------------------------------------------------------------
| 2B | Comment_Length | 2B | 2B | 2B |
--------------------------------------------------------------------------------------------------------
| Comment_Length | ‘signed by SignApk\0’ + (PKCS#7_SIG) | signature_start | \xff\xff | Comment_Length |
--------------------------------------------------------------------------------------------------------
signature_start = Comment_Length - len('signed by SignApk') - 1
(PKCS#7_SIG)是对对整个zip包(从ZIP头到<EOCD.CommentLength>之前)数据生成sha1,
再对sha1用私钥加密生成签名放在公钥证书尾部
整个Comment为PKCS#7格式(类似于CERT.RSA,只不过是对整个zip包数据做签名)
OTA包校验时也是先对ZIP包数据生成sha1,然后从ZIP尾部EOCD中取出Comment中的
最后256(2048bits)签名数据(SHA1WithRSA),用公钥解开再和sha1对比,一致则验证通过
// The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that
// the signing tool appends after the signature itself.
RSA_verify(pKeys+i, eocd + eocd_size - 6 - 256, 256, sha1)
========================================================================================
系统APK验证流程:
PackageManagerService :: collectCertificatesLI
PackageParser :: collectCertificates
-- if ((flags&PARSE_IS_SYSTEM) != 0)
// If this package comes from the system image, then we
// can trust it... we'll just use the AndroidManifest.xml
// to retrieve its signatures, not validating all of the files.
for system apk only, just verify AndroidManifest.xml, otherwise, verify all entry except "META-INF/"
JarFile jarFile = new JarFile(pkg);
JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
jarFile.getInputStream(je)
-- JarFile.getInputStream(ZipEntry) line: 378
-- JarVerifier.readCertificates() line: 258
-- JarVerifier.verifyCertificate(String) line: 330
-- JarVerifier.verify(Attributes, String, byte[], int, int, boolean, boolean) line: 405
1. Use .SF to verify the mainAttributes of the manifest
2. Use .SF to verify the whole manifest.
3. associate signatures with .SF and entries of manifest.
-- JarFile.getInputStream(ZipEntry) line: 395
-- JarVerifier.initEntry(String) line: 213
1. init entry digest method and it's hashbytes.
read inputStream
-- BufferedInputStream.read(byte[], int, int) line: 304
-- JarFile$JarFileInputStream.read(byte[], int, int) line: 119
-- JarVerifier$VerifierEntry.verify() line: 121
<<<
byte[] d = digest.digest();
if (!MessageDigest.isEqual(d, Base64.decode(hash))) {
throw invalidDigest(JarFile.MANIFEST_NAME, name, jarName);
}
verifiedEntries.put(name, certificates);
>>>>
1. hash content of jarEntry, cmp the digest with hashbytes already saved.
if they're identical, associate entry name with certificates.
Certificate[] certs = je.getCertificates();
-- JarEntry.getCertificates() line: 108
-- JarVerifier.getCertificates(String) line: 422
<<<
Certificate[] verifiedCerts = verifiedEntries.get(name);
>>>
------------------------------------------------------------------------------------------------------------------
Source snippet:
String pkg = "/mnt/asec/com.speedsoftware.rootexplorer-1/pkg.apk";
JarFile jarFile = new JarFile(pkg);
JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
byte[] readBuffer = new byte[8192];
try {
// We must read the stream for the JarEntry to retrieve
// its certificates.
InputStream is = new BufferedInputStream(jarFile.getInputStream(je));
while (is.read(readBuffer, 0, readBuffer.length) != -1) {
// not using
}
is.close();
Certificate[] certs = je.getCertificates();
Log.e(TAG, certs.toString());
} catch (IOException e) {
Slog.w(TAG, "Exception reading " + je.getName() + " in "
+ jarFile.getName(), e);
} catch (RuntimeException e) {
Slog.w(TAG, "Exception reading " + je.getName() + " in "
+ jarFile.getName(), e);
}
} catch (IOException e2) {
e2.printStackTrace();
}
- signapk流程分析
- android安全学习之6—signapk分析
- signapk.cmd
- 《Android软件安全与逆向分析》 signapk.jar签名apk工具--【整理学习分享,一部到位!】
- apk signapk.jar 解析
- SignApk.java 源码
- apktool--signapk.jar
- LightsService分析 --- 流程分析
- 用SignApk.jar 签名包
- 用SignApk.jar 签名包
- [Ceph分析]Fuse流程分析
- WTL流程分析
- linux开机流程分析
- 流程分析法
- Linux 开机流程分析
- WTL流程分析
- XFire客户端流程分析
- 测试流程分析
- ASP.NET产生随机验证码
- iOS 学习笔记 8 NSUserDefaults学习
- C的xml编程文章链接
- MSSQL2K - SQL Injector - Query String Parameter Attack结合netcat获得反向cmdshell
- Java语法总结 - 数组
- signapk流程分析
- UIButton,设置为UIButtonTypeCustom类型时,做圆角效果
- Java语法总结 - 字符串
- hdu 1166——敌兵布阵 (线段树)
- 我的梦想
- linux多线程----信号量
- JavaScript语言灵活性
- JAVA语法总结 - 异常
- nasm,打印的code