android签名机制

好久没有写博客了都荒废了,今天就随便写一点笔记也许以后还会用到。

故事要从很久以前说起,这是一个很长的故事,谁都不知道会不会有结局。这也是一个日常生活中经常发生的事情,自以为很聪明的项目经理+自以为项目经理是个sb的码农,滥俗的剧情。总之现在就在做android签名有关的项目。最近看了android系统的源代码改了一下做个记录以供查阅。

每个android的apk里都包含签名的信息。android系统可以安装任何带有合法签名的apk,如果一个apk没有签名信息那是无法在android上安装的。在我们平时用eclipse写android程序时他也在apk里加入了debug的签名信息,所以也是合法的可以安装的。为一个apk签名时,我们首先需要使用keytool这个工具,他会随机产生公私钥对,并根据输入的信息产生一个证书,把公钥打包进证书里。然后使用jarsigner,利用上一步生成的密钥和证书对apk进行签名。这两个工具在安装java时会自带。签完名的apk里面会有一个META-INF文件夹,里面包含了3个文件。jarsigner的过程就是生成这三个文件:1. 程序遍历apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Base64进行编码,写入MANIFEST.MF。2. 对MANIFEST.MF中的信息使用SHA1-RSA算法,用私钥进行签名,写入CERT.SF。3. 将公钥、所用的加密算法等信息写入CERT.RSA。具体参见http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html

下面讲一讲源代码里对签名的检测。原生android中只会检测是否有签名,签名是否合法(程序的完整性)。看了好久的源代码之后,发现安装一个apk时会首先进入packages/apps/packageinstaller这个系统级的应用里,在这里会对apk进行一系列预处理,最后调用到PackageManagerService里的installPackageWithVerification函数。安装apk还有一种方法就是通过调用adb install来安装,这时候会直接调用installPackageWithVerification函数。所以如果想控制apk的安装,直接截住源头是最好的方法。通过对几千行代码的研读,最后决定在installPackageLI这个函数里对apk的签名进行检测,不是特定签名的apk就不安装。在对签名进行检测的时候,参考了android自带的对OTA签名进行检测的部分代码。执行keytool -export -keystore mystore -alias mykey -file my.pem -rfc生成pem文件,打包成zip放到手机里(比如sdcard)。安装apk时只要检测apk的公钥和zip包里的公钥是否一致即可检测出apk是否可信任。部分关键代码如下:

boolean verified = false;
HashSet<Certificate> trusted = new HashSet<Certificate>();
try {
ZipFile zip = new ZipFile(“/mnt/sdcard/mykey.zip”);
try {
CertificateFactory cf = CertificateFactory.getInstance(“X.509”);
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
trusted.add(cf.generateCertificate(zip.getInputStream(entry)));
}
} catch (CertificateException e) {
e.printStackTrace();
} finally {
zip.close();
}
PublicKey signatureKey = mPkgInfo.mSignatures[0].getPublicKey();

for (Certificate c : trusted) {
if (c.getPublicKey().equals(signatureKey)) {
verified = true;
break;
}
}

实际修改时发现PackageManagerService不能读取sdcard中的文件,各种方法找不出原因,最后把文件放到系统目录里就解决了。

其实还有个修改系统锁屏的项目,感觉那个更有意思更贴近生活,比如做个很可爱的锁屏,让妹子的手机变成全天下独一无二之类的。可惜做到一半转交给另一个同学了,现在看他貌似很痛苦的样子=______=||

虽然故事还没完,但也要来个中期小结什么的。下面简单说两点:1. android源代码很有意思,要不是毕业压力那么大,我倒是很想改出一个很不错的系统,独一无二量身定做。2. XX所的人水平真的不怎么样,想搞安全却连最基本的密码学知识也不去补习一下,都不如我这个只上过几节课的人高。当然也许只是跟我们合作的这些人比较菜,不知道幕后有没有什么大神。感觉以后如果找不到工作去研究所还是能混一混的,交大的同学一定要对自己有信心。

android签名机制》有1个想法

发表评论

您的电子邮箱地址不会被公开。