Android正式签名打包的过程

来源:互联网 发布:黑帽子数据 编辑:程序博客网 时间:2024/04/30 11:55

1.  为什么要签名?

1)         发送者的身份认证 

    开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的。

2)         保证信息传输的完整性 

    由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,签名可以保证相同的名字,但是签名不同的包不被替换。

    APK如果使用一个key签名,发布时另一个key签名的文件将无法安装或覆盖老的版本,这样可以防止你已安装的应用被恶意的第三方覆盖或替换掉。

3)         防止交易中的抵赖发生,    

    签名其实也是开发者的身份标识。交易中抵赖等事情发生时,签名可以防止抵赖的发生 Market 对软件的要求)


2.  签名的说明

1)         所有的应用程序都必须有数字证书 Android 系统不会安装一个没有数字证书的应用程序

2)         Android 程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证

3)         如果要正式发布一个 Android 应用,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用 adt 插件或者ant 工具生成的调试证书来发布

4)         数字证书都是有有效期的, Android 只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能

5)         签名后需使用 zipalign 优化程序

6)         Android 数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,而不是用来决定最终用户可以安装哪些应用程序

7)        如果你用Eclipse里的Runl来生成Apk,是不会混淆代码的,需要手动的打包有正式签名的apk才会混淆代码。


3.签名策略

应用程序签名的一些方面可能会影响应用程序的开发过程, 尤其是当你计划发布多个应用时. 通常情况下, 对于所有开发者而言, 推荐的策略是:在应用程序的整个生命周期,所有的应用程序使用相同的证书签名.

为什么这么做?
1、应用程序升级 – 当发布应用的更新时, 如果想让用户无缝地升级到新版本, 需要继续使用相同的某个或者某一套证书来签名更新包. 当系统安装应用的更新时, 它会比较现有版本和新版本的证书. 如果证书吻合, 包括证书数据和顺序都吻合, 那么系统允许更新. 如果新版本所做的签名不是匹配的, 那么将需要给应用起一个不同的包名 — 在这种情况下, 用户相当于安装了一个完全的新程序.
2、应用程序模块化 – Android允许由相同证书签名的应用程序运行在相同的进程中, 此时系统会将它们作为单个应用程序对待. 在这种方式中, 可以按模块化的方式部署应用, 用户可以根据需要独立地更新每一个模块.

3、代码/数据 的授权共享 – Android 提供模式匹配的权限控制机制, 因此一个应用可以暴露功能给另一个用指定证书签名的应用. 通过用相同证书签名多个应用,以及使用模式匹配的权限检查, 应用程序可以以安全的方式共享代码和数据.

如何设置签名应用的key的有效期?
如果计划为某个单独的应用程序提供更新支持, 那么应该确认key的有效期要比应用的寿命长. 推荐25年或者更长的有效期. 当key的有效期过期, 用户将再也不能无缝地更新到应用程序的新版本.
如果要使用相同的key为多个不同的应用签名, 应当确认key的有效期比所有这些应用的所有版本的生命周期还长, 包括要比将来加到这个套件中的额外的关联应用的生命周期更长.
如果计划将应用程序发布到Android Market, 为应用签名的key的有效期必须在2033年10月22日以后. Market服务器强制执行这个规则, 来保证当新版本可用时, 用户可以无缝地更新Market应用.
当设计的时候, 须牢记这些要点, 以确保使用合适的证书来签名应用程序.

4. 签名的方法过程

1)          eclipse 插件方式签名

a)          调试签名 
eclipse 
插件默认赋予程序一个 DEBUG 权限的签名,此签名的程序不能发布到 market 上,此签名有效期为一年,如果过期则导致你无法生成 apk 文件,此时你只要删除 debug keystore 即可,系统又会为你生成有效期为一年的新签名

b)         开发者生成密钥并签名 
右键点击项目名,在菜单中选择 Android Tools ,然后选择 Export Signed Application Package… ,即可通过eclipse 自定义证书并签名

具体操作如下:

1、选中要发布的项目右键选中Android Tools然后选择 Export Signed Application Package…




2、进入后选择要打包的项目点击next



这里有两个选择,如果项目已经有签名证书可以选择使用以前的证书,

如果是第一次签名,还没有签名证书,所以先create new keystore,以后就不再创建了,直接选择已存在的证书。

我们这里先自己创建一个签名证书:

Location:证书要存放的路径

Password:签名证书的密码,以后如果还想使用这个证书就需要输入正确的密码,注意保存好

Confirm:再次输入密码确认




点击next进入创建签名的页面,这里我们需要填写的信息包括:别名,密码,有效期,姓名,组织,组织名称,所在城市,所在省份,国家等,然后next。





选择你要存储打包后的apk 的路径后点击finish:




这样就生成了一个打包好有正式签名的apk和签名证书。


如何查看签名证书?

在你保存签名证书的目录按住shift键同时点击鼠标右键,选择在此打开命令行(或者通过命令一步一步进入保存签名证书的目录):




在命令行中输入命令: keytool -list -v -keystore keystoreName -storepass keystorePassword

就可以查看签名证书中的内容了。




c)          开发者导出未签名的包 
右键点击项目名,在菜单中选择 Android Tools ,然后选择 Export UnSigned 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=MountainView/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 ,表示不加密,所以签名时不用输入密码

5. 签名的相关文件

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/*

6.签名的相关问题 
一般在安装时提示出错: INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

1)         两个应用,名字相同,签名不同

2)         升级时前一版本签名,后一版本没签名

3)         升级时前一版本为 DEBUG 签名,后一个为自定义签名

4)         升级时前一版本为 Android 源码中的签名,后一个为 DEBUG 签名或自定义签名

5)         安装未签名的程序

6)         安装升级已过有效期的程序

7. 相关工具

1)         查看某个 x509 证书的的有效日期 
 SignApk.java 中打印出 publicKey.getNotAfter() 即可



0 0