Android学习之路(1) -- APK签名

离开校园,工作也有三个月了,一直都忙于公司的项目或者瞎折腾,今天开始,好好的开始学习Android,从零出发。

自从学习Android以来,一直都是自学,用到啥学啥,很乱,没有系统的去梳理Android的知识,在博客园看到一位博主:谦虚的天下,从2011年4月一直更新到2015年1月Android学习系列;想以这个为指导,进行现阶段的Android学习。

今天学习了APK的签名,并记录下来,方便以后复习或查阅。

谦虚的天下的这篇博文由于是2011年发表的,有些过时,在实现的时候出现一些问题,通过一番查询也解决,好了,进入这篇文章的正题:

任务目标

  1. 为什么签名
  2. 通过命令行完成签名
  3. 通过Android Studio(简称:AS)完成签名

为什么签名

为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性(如自动更新不会因为版本不一致而无法安装)。

命令行签名

  • 未签名的apk
  • 签名工具的配置
  • 具体操作

通过AS导出未签名的apk

AS不能直接导出未签名的apk,需要通过gradle来导出。打开AS,直接新建一个默认项目,用于签名测试的Demo。

《Android学习之路(1) -- APK签名》 导出未签名apk的示意图
《Android学习之路(1) -- APK签名》 导出成功示意图
《Android学习之路(1) -- APK签名》 导出包路径示意图

这样,未签名的apk包就导出来了,第一步准备工作就完成了。

签名工具的配置

用到的签名工具:

  • keytool.exe
  • jarsigner.exe

keytool.exe生成key,位于C:\Program Files\Java\jre1.8.0_25\bin目录下(jre的安装目录),jarsigner.exe用生成的key对apk签名,位于C:\Program Files\Java\jdk1.8.0_25\bin目录下(jdk的安装目录),把这两个的路径添加到环境变量path后,就完成了签名工具的配置。

具体操作

keytool参数选项说明:

Keytool 选项描述
-genkey产生一个键值对(公钥和私钥)
-v允许动作输出
-alias<alias_name>键的别名。只有前八位字符有效。
-keyalg产生键的加密算法。支持DSA和RSA。
-keysize产生键的长度。如果不支持,keytool用默认值1024 bits.通常我们用2048 bits 或更长的key。
-dname专有名称,描述谁创建的密钥。该值被用作自签名证书的颁发者和主题字段。注意你可以不在命令行指定。如果没有指定keytool会提示你(CN, OU, and so on)。
-keypass键的密码。主要为了安全起见,如果没提供,keytool会提示你输入。
-validity键的有效期,单位:天。</br>Note: A value of 10000 or greater is recommended.
-keystore.keystore用于存储私钥的文件。
-storepass私钥存储文件的密码。主要为了安全起见,如果没提供,keytool会提示你输入。这个密码不会存储在你的shell历史记录中。

使用keytool创建签名key,打开windows 10的命令窗口,输入命令:

keytool -genkey -v -alias demo -keyalg RSA -validity 40000 -keystore demo.keystore

参数说明:

-genkey             产生密钥
-alias              demo.keystore的别名demo
-keyalg RSA         使用RSA算法对签名加密
-validity 40000     有效期限4000天
-keystore           demo.keystore 

说明:输入此命令前,先进入你想将创建的key保存的目录,比如,我现在要将keystore保存在D盘根目录,则

《Android学习之路(1) -- APK签名》 创建签名key的示意图

这样,签名key就创建成功了。
接着,对未签名的apk进行签名,先把未签名的apk放到你生成的keystore的目录。

jarsigner参数选项说明:

Jarsigner 选项描述
-keystore.keystore包含你私钥的存储文件
-verbose显示输出动作
-sigalg签名算法,用 SHA1withRSA
-digestalg消息摘要算法,用 SHA1
-storepass存储文件的密码</br>主要为了安全起见,如果没提供,jarsigner会提示你输入。这个密码不会存储在你的shell历史记录中。
-keypass私钥的密码</br>主要为了安全起见,如果没提供,jarsigner会提示你输入。这个密码不会存储在你的shell历史记录中。

JDK1.6命令:

jarsigner -verbose -keystore demo.keystore -signedjar app-signed.apk app-unsigned.apk demo

参数说明:

-verbose 输出签名的详细信息
-keystore demo.keystore密钥库的位置
-signedjar app-signed.apk app-unsigned.apk   demo.keystore 正式签名,app-signed.apk是
app-unsigned.apk签名后生成的apk,文件名可自定义,app-unsigned.apk是放在demo.keystore文件
同一目录的未签名apk
demo  demo.keystore的别名

JDK1.7以上 命令:(JDK1.7 算法发生了变化,需要指定 -sigalg 和 -digestalg)

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore demo.keystore -signedjar app-signed.apk app-unsigned.apk demo

《Android学习之路(1) -- APK签名》 生成签名apk

《Android学习之路(1) -- APK签名》 签名成功

如上图,签名成功后出现警告,这个警告对签名并没有影响,但看着怪不舒服的,要去掉的话只要在命令上加上
-tsa https://timestamp.geotrust.com/tsa就可以了。

《Android学习之路(1) -- APK签名》 最终命令

通过Android Studio(简称:AS)完成签名

IDE工具签名很容易就可以完成,看下图:

《Android学习之路(1) -- APK签名》 AS签名apk

根据提示,填写相应的内容,即可完成签名,这里就不进一步说明了。

遇到的问题及解决方法

1.生成的签名apk不能安装

《Android学习之路(1) -- APK签名》 问题一

出现上图,红色框的提示导致签名apk无法安装,原因是真机或者模拟器的Android版本小于签名apk的最小sdk版本,比如我现在的这个apk的最小sdk版本是19,而我的真机版本是17。

《Android学习之路(1) -- APK签名》 解决方法

2.签名apk不能重复安装

《Android学习之路(1) -- APK签名》 问题二

出现上图,红色框的提示安装失败,是因为这个apk已经安装过了。

解决方法:

//执行安装命令是,增加-r参数
adb install -r app-signed.apk

3.签名冲突

《Android学习之路(1) -- APK签名》 签名冲突

出现上图,红色框的提示安装失败,是因为签名冲突造成的,比如你使用了ADB的debug权限签名,但后来使用标准sign签名后再安装同一个文件会出现这样的错误提示,解决的方法除了只有先老老实实从手机上卸载原有版本再进行安装,而adb install -r参数也无法解决这个问题。

《Android学习之路(1) -- APK签名》 安装签名apk成功

总结

哪怕再小的知识点,也要认真的去学习,一点一点的去积累,去成长,写的有什么不对的,希望各位路过的大牛们指点指点,拜谢。

    原文作者:萌太浪
    原文地址: https://www.jianshu.com/p/74c6cbb02d49
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞