android签名机制
发布过Android应用的朋友们应该都知道,Android APK的发布是需要签名的。签名机制在Android应用和框架中有着十分重要的作用。例如,Android系统禁止更新安装签名不一致的APK;如果应用需要使用system权限,必须保证APK签名与Framework签名一致,等等。在《APK Crack》一文中,我们了解到,要破解一个APK,必然需要重新对APK进行签名。而这个签名,一般情况无法再与APK原先的签名保持一致。(除非APK原作者的私钥泄漏,那已经是另一个层次的软件安全问题了。简单地说,签名机制标明了APK的发行机构。因此,站在软件安全的角度,我们就可以通过比对APK的签名情况,判断此APK是否由“官方”发行,而不是被破解篡改过重新签名打包的“盗版软件”。
目前主要的签名有两种方式,签名包括2 种,第一种是对APK 签名,即开发者开发的应用;第二种是对Android img 签名,保证img文件的完整性和后续升级,如果img文件被破解的话,则不能升级到最新的版本,应用apk也是同样的原理,这也是apk被破解不能升级的原因。
在linux系统下编译的时候,将会使用google原生的key的apk和应用进行签名,签名的脚步和key分别保存在如下的路径,有兴趣的话,可以研究一下:
android\build\tools\releasetools build\target\product\security
android默认的key主要有以下几种类型,每种key对应的权限不同:
testkey(releasekey) -- a generic key for packages that do not otherwise specify a key. 开发过程中的key
platform -- a test key for packages that are part of the core platform. 当APK 完成一些系统的核心功能时使用,这种方式编译出来的APK所在进程的UID 为system。
shared -- a test key for things that are shared in the home/contacts process. 当APK 需要和home/contacts 进程共享数据时使用
media -- a test key for packages that are part of the media/download system. 当APK 是media/download 系统中的一环时使用
如何生成自己的key,主要有两种方法,一种是使用keytool工具,比较简单,在调试应用程序时,Android SDK工具会自动对应用程序进行了签名。Eclipse的ADT插件和Ant编译工具都提供了两种签名模式——Debug模式和Release模式。 在开发和测试时,可以使用Debug模式。Debug模式下,编译工具使用内嵌在JDK中的Keytool工具来创建一个keystore和一个 key(包含公认的名字和密码)。在每次编译的时候,会使用这个Debug
Key来为apk文件签名。由于密码是公认的所以每次编译的时候,并不需要提示你输入keystore和key密码。另外一种是使用make_key工具生成签名文件
development/tools$ sh make_key releasekey '/C=CN/ST=JiangSu/L=NanJing/O=Company/OU=Department/CN=YourName/emailAddress=YourE-mailAddress'
Enter password for 'releasekey' (blank for none; password will be visible): mypassword <------- 设置你的密码
creating platform.pk8 with password [mypassword]
Generating RSA private key, 2048 bit long modulus e is 3 (0x3)
这里要顺便介绍下make_key的参数。第一个参数是要生成key的名字,第二个参数是关于你公司的邮箱,具体的参数可以看说明。
下来,我们分别看一下对apk和img签名的方法。
1 APK签名
查看apk签名的方法如下:jarsinger -verify -verbose -certs apk(apk名称) 可以查看签名的信息。查询结果:没有清单。 表示jar未签名。如果是用Eclipse+SDK开发,则会有一个默认的签名,查看如下:
sm 1752 Fri Dec 05 10:45:42 CST 2014 AndroidManifest.xml
X.509, CN=Android Debug, O=Android, C=US [证书的有效期为 14-1-28 下午5:38 至 44-1-21 下午5:38]
可以使用signapk.jar对apk进行签名,在源码中的位置如下:
可以在platform/build/target/product/security/中找到platform.pk8 platform.x509.pem等签名文件,对应不同的权限。
signapk.jar:由/platform/build/tools/signapk/编译产出,可以在/out/host/linux-x86/framework/中找到。
签名:java -jar signapk.jar platform.x509.pem platform.pk8 MyDemo.apk MyDemo_signed.apk 得到具有对应权限的APK
优化APK:zipalign -v 4 MyDemo_signed.apk MyDemo_new.apk
2 img文件签名
这种比较简单,一是在系统编译前,直接使用用自己的key替换掉android原生的key,编译完,系统就是用新的key签过名了;二是在编译完,分别对apk和img文件签名,主要有以下两个步骤,直接从别的博客copy过来。
1对apk进行签名
android_src$ ./build/tools/releasetools/sign_target_files_apks -d vendor/Modul/security/product_modul/ out/dist/product_modul-target_files.zip out/dist/signed_target_files.zip
ERROR: no key specified for:
CalendarWidget.apk
Contacts_yellowpage.apk
SnsAppMain.apk
fbandroid-1.5.0.apk
AnalogClockWidget.apk
MessageWidget.apk
NewsWidget.apk
上面的意思是使用sign_target_files_apks工具采用vendor/Modul/security/product_modul /下的key对product_modul-target_files.zip文件进行签名,并把签名结果放在out/dist /signed_target_files.zip里.
从上面的签名结果看,签名并没有成功,原因是由于有些apk程序已经签过名了或者找不到对应的key. 这也难不倒我们,我们可以通过设置过滤,不对上面的程序进行签名.方法如下:
通过参数"-e <apkname>=" 来过滤这些程序.
android_src$ ./build/tools/releasetools/sign_target_files_apks -d vendor/Modul/security/product_modul/ -e CalendarWidget.apk= -e Contacts_yellowpage.apk= -e SnsAppMain.apk= -e fbandroid-1.5.0.apk= -e AnalogClockWidget.apk= -e MessageWidget.apk= -e NewsWidget.apk= out/dist/product_modul-target_files.zip out/dist/signed_target_files.zip
Enter password for vendor/Modul/security/product_modul//media key> <----- imput the password
Enter password for vendor/Modul/security/product_modul//platform key> <----- imput the password
Enter password for vendor/Modul/security/product_modul//releasekey key> <----- imput the password
Enter password for vendor/Modul/security/product_modul//shared key> <----- imput the password
rewriting RECOVERY/RAMDISK/default.prop:
replace: ro.build.tags=test-keys
with: ro.build.tags=release-keys
NOT signing: CalendarWidget.apk
NOT signing: Contacts_yellowpage.apk
signing: Mms.apk
signing: SoundRecorder.apk
signing: AccountAndSyncSettings.apk
signing: Camera.apk
.......................................................................
rewriting SYSTEM/build.prop:
replace: ro.build.tags=test-keys
with: ro.build.tags=release-keys
replace: ro.build.description= test-keys
with: ro.build.description= release-keys
replace: ro.build.fingerprint=...........................
with: ro.build.fingerprint=.............................
signing: framework-res.apk
done.
这样就完成了android系统的签名工作.
2 对img进行签名
android_src$ ./build/tools/releasetools/img_from_target_files out/dist/signed-target-files.zip out/dist/signed-img.zip
creating boot.img...
creating recovery.img...
creating system.img...
creating userdata.img...
cleaning up...
done.
使用img_from_target_files工具生成signed-img.zip文件.signed-img.zip文件包含了boot.img,userdate.img,system.img文件等.