在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的protectionLevel为signature,那么就只有那些跟该permission所在的程序拥有同一个数字证书的应用程序才能取得该权限。Android使用Java的数字证书相关的机制来给apk加盖数字证书,要理解android的数字证书,需要先了解以下数字证书的概念和java的数字证书机制。Android系统要求每一个安装进系统的应用程序都是经过数字证书签名的,数字证书的私钥则保存在程序开发者的手中。Android将数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序。这个数字证书并不需要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。
在整个平台的安全性方面Google也使用了Android签名机制,当然这里使用Sun的针对Jar文件签名工具jarsigner即可,这里我们需要了解一些问题,为什么要签名?其实安装到真机G1的软件都必须签名。

平时我们在AndroidMarket上下载的软件都必需签名,所以说上传时是免不了这个操作的,常规的签名步骤可以查看Android签名用keytool和jarsigner制作apk文件这点Google设计的还好,没有像Symbian那样针对S60第三版和第五版都需要花费每次200美元的测试费用,如果遇到了ZipExceptioninvalidentrycompressedsize的错误方法过去我们在无法对jar进行签名,Androidjarsigner问题一文中提到了,主要原因是平时Eclipse使用的ADT插件已经赋予了DEBUG权限的数字签名,我们可以通过导出一个未签名的APK文件就可以解决,参考如何导出一个未签名的APK文件?即可顺利的签名。

一、同一个开发者的多个程序尽可能使用同一个数字证书,这可以带来以下好处。
(1)有利于程序升级,当新版程序和旧版程序的数字证书相同时,Android系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。
(2)有利于程序的模块化设计和开发。Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。
(3)可以通过权限(permission)的方式在多个程序间共享数据和代码。Android提供了基于数字证书的权限赋予机制,应用程序可以和其他的程序共享概功能或者数据给那那些与自己拥有相同数字证书的程序。如果某个权限(permission)的protectionLevel是signature,则这个权限就只能授予那些跟该权限所在的包拥有同一个数字证书的程序。

在签名时,需要考虑数字证书的有效期:
(1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改数字证书的程序将不能正常升级。
(2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序的预计生命周期。
(3)AndroidMarket强制要求所有应用程序数字证书的有效期要持续到2033年10月22日以后。

二、Android数字证书包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个Android,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。
(5)Android使用标准的java工具KeytoolandJarsigner来生成数字证书,并给应用程序包签名。
(6)使用zipalign优化程序。

Android系统不会安装运行任何一款未经数字签名的apk程序,无论是在模拟器上还是在实际的物理设备上。Android的开发工具(ADT插件和Ant)都可以协助开发者给apk程序签名,它们都有两种模式:调试模式(debugmode)和发布模式(releasemode)。
在调试模式下,android的开发工具会在每次编译时使用调试用的数字证书给程序签名,开发者无须关心。
当要发布程序时,开发者就需要使用自己的数字证书给apk包签名,可以有两种方法。
(1)在命令行下使用JDK中的和Keytool(用于生成数字证书)和Jarsigner(用于使用数字证书签名)来给apk包签名。
(2)使用ADTExportWizard进行签名(如果没有数字证书可能需要生成数字证书)。

三、两种签名方式

第一种签名方式:使用Keytool和Jarsigner给程序签名(用于1.5以下版本)
命令:keytool-genkey-v-keystoreandroid.keystore-aliasandroid-keyalgRSA-validity20000
该命令中,-keystoreophone.keystore表示生成的证书,可以加上路径(默认在用户主目录下);-aliasophone表示证书的别名是ophone;-keyalgRSA表示采用的RSA算法;-validity20000表示证书的有效期是20000天。

Android程序的签名和Symbian类似都可以自签名(Self-signed),但是在Android平台中证书初期还显得形同虚设,平时开发时通过ADB接口上传的程序会自动被签有Debug权限的程序。需要签名验证在上传程序到AndroidMarket上时大家都已经发现这个问题了。Androidsigned制作方法
首先在Android开发时没有安装JDK的网友在Sun官方网站下载JDKhttp://www.java.net/download/jdk...6-p-12_sep_2008.exe,其实仅需要中的Keytool和Jarsigner。
详细的签名步骤:
第一步
C:\ProgramFiles\Java\jdk1.6.0_10\bin>keytool-genkey-aliasandroid123.keystore
-keyalgRSA-validity20000-keystoreandroid123.keystore
输入keystore密码:[密码不回显]
再次输入新密码:[密码不回显]
您的名字与姓氏是什么?
[Unknown]:android123
您的组织单位名称是什么?
[Unknown]:www.android123.com.cn
您的组织名称是什么?
[Unknown]:www.android123.com.cn
您的组织名称是什么?
[Unknown]:www.android123.com.cn
您所在的城市或区域名称是什么?
[Unknown]:NewYork
您所在的州或省份名称是什么?
[Unknown]:NewYork
该单位的两字母国家代码是什么
[Unknown]:CN
CN=android123,OU=www.android123.com.cn,O=www.android123.com.cn,L=NewYork,ST
=NewYork,C=CN正确吗?
[否]:Y
输入<android123.keystore>的主密码
(如果和keystore密码相同,按回车):
其中参数-validity为证书有效天数,这里我们写的大些20000天。还有在输入密码时没有回显,只管输入就可以了,一般位数建议使用20位,最后需要记下来后面还要用,整 个 过程如图:
接下来我们开始为apk文件签名了。


第二步
执行下面这句jarsigner-verbose-keystoreandroid123.keystore-signedjarandroid123_signed.apkandroid123.apkandroid123.keystore就可以生辰签名的apk文件,这里输入文件android123.apk,最终生成android123_signed.apk为Android签名后的APK执行文件。下面提示输入的密码和keytool输入的一样就行了
有关Android程序发布和签名可以查看SDK中http://code.google.com/android/devel/sign-publish.html一文.
附上keytool参数以及jarsigner参数:
keytool用法:
-certreq[-v][-protected]
[-alias<别名>][-sigalg<sigalg>]
[-file<csr_file>][-keypass<密钥库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-changealias[-v][-protected]-alias<别名>-destalias<目标别名>
[-keypass<密钥库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-delete[-v][-protected]-alias<别名>
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-exportcert[-v][-rfc][-protected]
[-alias<别名>][-file<认证文件>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-genkeypair[-v][-protected]
[-alias<别名>]
[-keyalg<keyalg>][-keysize<密钥大小>]
[-sigalg<sigalg>][-dname<dname>]
[-validity<valDays>][-keypass<密钥库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-genseckey[-v][-protected]
[-alias<别名>][-keypass<密钥库口令>]
[-keyalg<keyalg>][-keysize<密钥大小>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-help
-importcert[-v][-noprompt][-trustcacerts][-protected]
[-alias<别名>]
[-file<认证文件>][-keypass<密钥库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-importkeystore[-v]
[-srckeystore<源密钥库>][-destkeystore<目标密钥库>]
[-srcstoretype<源存储类型>][-deststoretype<目标存储类型>]
[-srcstorepass<源存储库口令>][-deststorepass<目标存储库口令>]
[-srcprotected][-destprotected]
[-srcprovidername<源提供方名称>]
[-destprovidername<目标提供方名称>]
[-srcalias<源别名>[-destalias<目标别名>]
[-srckeypass<源密钥库口令>][-destkeypass<目标密钥库口令>]]
[-noprompt]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-keypasswd[-v][-alias<别名>]
[-keypass<旧密钥库口令>][-new<新密钥库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-list[-v|-rfc][-protected]
[-alias<别名>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
-printcert[-v][-file<认证文件>]
-storepasswd[-v][-new<新存储库口令>]
[-keystore<密钥库>][-storepass<存储库口令>]
[-storetype<存储类型>][-providername<名称>]
[-providerclass<提供方类名称>[-providerarg<参数>]]...
[-providerpath<路径列表>]
jarsigner用法:[选项]jar文件别名
jarsigner-verify[选项]jar文件
[-keystore<url>]密钥库位置
[-storepass<口令>]用于密钥库完整性的口令
[-storetype<类型>]密钥库类型
[-keypass<口令>]专用密钥的口令(如果不同)
[-sigfile<文件>].SF/.DSA文件的名称
[-signedjar<文件>]已签名的JAR文件的名称
[-digestalg<算法>]摘要算法的名称
[-sigalg<算法>]签名算法的名称
[-verify]验证已签名的JAR文件
[-verbose]签名/验证时输出详细信息
[-certs]输出详细信息和验证时显示证书
[-tsa<url>]时间戳机构的位置
[-tsacert<别名>]时间戳机构的公共密钥证书
[-altsigner<类>]替代的签名机制的类名
[-altsignerpath<路径列表>]替代的签名机制的位置
[-internalsf]在签名块内包含.SF文件
[-sectionsonly]不计算整个清单的散列
[-protected]密钥库已保护验证路径
[-providerName<名称>]提供者名称
[-providerClass<类>加密服务提供者的名称
[-providerArg<参数>]]...主类文件和构造函数参数
此时,我们会在互用主目录下看到ophone.keystore,即我们刚刚创建的证书。

第二种签名方式:现在介绍android1.5及更新版本的apk签名方式

1、打开Eclipse->选择你要签名的项目->右击->androidtools->ExportsignedApplicationpackage...

2、跳出窗口


3、projectchecks如果核对项目名没有问题的话点击Next
然后跳出keystoreselection如果是已经存在keystore的文件就选择然后next输入keystore的密码进行签名。
如果没有的话选择createnewkeystore然后选择keystore保存的位置,设置keystore的密码,点击Next。

4、填写keystore的基本信息,如,别名,密码,有效期,姓名,组织,组织名称,所在城市,所在省份,国家等,点击Next


5、选择被签名后的APK保存位置。点击finish。


6、就可以在你保存的位置中找到相应的被签名后的APK文件。


以上的签名只有在ANDROID1.5以及以后的版本适用。谢谢。
希望对大家有帮助,谢谢。

Android签名教程文档下载:Android签名教程


更多相关文章

  1. 高德地图的调试版SHA1与发布版SHA1分别的获取,申请到KEY
  2. Android应用程序整合第三方API(以高德Map API为例)
  3. Android(安卓)取得应用程序的启动次数和运行时间等信息
  4. [置顶] Android代码混淆
  5. Android-电量优化
  6. Android(安卓)NDK编译带STL的 C/C++ 程序
  7. Android(安卓)Studio运行程序出现Session ‘app’: Error Launch
  8. 初学Android应用程序——资源文件、文字、字体颜色、文字背景颜
  9. 安卓自学应用程序生命周期法

随机推荐

  1. Android(安卓)自定义Gallery
  2. 【Android】利用广播Broadcast接收SMS短
  3. 《Android(安卓)计算器》
  4. 手机横屏时,键盘默认全屏显示
  5. android时间控件TimePicker使用实例
  6. android 动画1
  7. Android基于TitleBar页面导航实现
  8. android 动态加载Listview
  9. Android原生壁纸加载日志
  10. Android放大镜的实现