1) 发送者的身份认证
因为开发商可能经过使用相同的Package Name来混淆替换已经安装的程序,以此保证签名不一样的包不被替换html
2) 保证信息传输的完整性
签名对于包中的每一个文件进行处理,以此确保包中内容不被替换java
3) 防止交易中的抵赖发生,Market对软件的要求android
2. 签名的说明算法
1) 全部的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序app
2) Android程序包使用的数字证书能够是自签名的,不须要一个权威的数字证书机构签名认证eclipse
3) 若是要正式发布一个Android应用,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布ide
4) 数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。若是程序已经安装在系统中,即便证书过时也不会影响程序的正常功能工具
5) 签名后需使用zipalign优化程序优化
6) Android将数字证书用来标识应用程序的做者和在应用程序之间创建信任关系,而不是用来决定最终用户能够安装哪些应用程序ui
3. 签名的方法
1) 用eclipse插件方式签名
a) 调试签名
eclipse插件默认赋予程序一个DEBUG权限的签名,此签名的程序不能发布到market上,此签名有效期为一年,若是过时则致使你没法生成apk文件,此时你只要删除debug keystore便可,系统又会为你生成有效期为一年的新签名
b) 开发者生成密钥并签名
右键点击项目名,在菜单中选择Android Tools,而后选择Export Signed Application Package…,便可经过eclipse自定义证书并签名
c) 开发者导出未签名的包
右键点击项目名,在菜单中选择Android Tools,而后选择Export Signed Application Package…,便可导出未签名的包,以后可经过命令行方式签名
2) 用命令行方式签名
使用标准的java工具keytool和jarsigner来生成证书和给程序签名
a) 生成签名
$ keytool -genkey -keystore keyfile -keyalg RSA -validity 10000 -alias yan
注:validity为天数,keyfile为生成key存放的文件,yan为私钥,RSA为指定的加密算法(可用RSA或DSA)
b) 为apk文件签名
$ jarsigner -verbose -keystore keyfile -signedjar signed.apk base.apk yan
注:keyfile为生成key存放的文件,signed.apk为签名后的apk,base.apk 为未签名的apk,yan为私钥
c) 看某个apk是否通过了签名
$ jarsigner -verify my_application.apk
d) 优化(签名后须要作对齐优化处理)
$ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk
3) 在源码中编译的签名
a) 使用源码中的默认签名
在源码中编译通常都使用默认签名的,在某源码目录中用运行
$ mm showcommands能看到签名命令
Android提供了签名的程序signapk.jar,用法以下:
$ signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar
*.x509.pem为x509格式公钥,pk8为私钥
build/target/product/security目录中有四组默认签名可选:testkey, platform, shared, media(具体见README.txt),应用程序中Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪一个key签名,未指定的默认用testkey.
b) 在源码中自签名
Android提供了一个脚本mkkey.sh(build/target/product/security/mkkey.sh),用于生成密钥,生成后在应用程序中经过Android.mk中的LOCAL_CERTIFICATE字段指名用哪一个签名
c) mkkey.sh介绍
i. 生成公钥
openssl genrsa -3 -out testkey.pem 2048
其中-3是算法的参数,2048是密钥长度,testkey.pem 是输出的文件
ii. 转成x509格式(含做者有效期等)
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 -subj ‘/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com’
iii. 生成私钥
openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt
把的格式转换成PKCS #8,这里指定了-nocryp,表示不加密,因此签名时不用输入密码
4. 签名的相关文件
1) apk包中签名相关的文件在META_INF目录下
CERT.SF:生成每一个文件相对的密钥
MANIFEST.MF:数字签名信息
xxx.SF:这是 JAR 文件的签名文件,占位符 xxx标识了签名者
xxx.DSA:对输出文件的签名和公钥
2) 相关源码
development/tools/jarutils/src/com.anroid.jarutils/SignedJarBuilder.java
frameworks/base/services/java/com/android/server/PackageManagerService.java
frameworks/base/core/java/android/content/pm/PackageManager.java
frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java
dalvik/libcore/security/src/main/java/java/security/Sign*
build/target/product/security/platform.*
build/tools/signapk/*
5. 签名的相关问题
通常在安装时提示出错:INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
1) 两个应用,名字相同,签名不一样
2) 升级时前一版本签名,后一版本没签名
3) 升级时前一版本为DEBUG签名,后一个为自定义签名
4) 升级时前一版本为Android源码中的签名,后一个为DEBUG签名或自定义签名
5) 安装未签名的程序
6) 安装升级已过有效期的程序
6. 相关工具
1) 查看某个x509证书的的有效日期
在SignApk.java中打印出publicKey.getNotAfter()便可
7. 参考
http://developer.android.com/guide/publishing/app-signing.html
http://www.pgcw.com.cn/Newsdetail.asp?id=257565010
http://www.eoeandroid.com/thread-23010-1-1.html
http://pepa.javaeye.com/blog/250991