Android应用市场一般都要求apk先进行签名才可上传应用,基于安全原则很多平台加入了apk需加固后才能上传的规则;
这时候就面临一个问题,因为apk加固后,会被抹除原有的签名信息,有些平台提供了官方的加固方式,加固的同时会要求你配置好签名信息,之后便可一次完成;但是部分apk通过不同安全平台的加固后,都需要开发者手动签名加固包!故才有了此篇的意义 ~
因为apk签名相关内容涉及到了keystore、jsk签名证书,故此推荐一下keystore、jks的知识扩展 ~
- keystore、jks基础知识
- 生成keystore、jks 签名证书
- 反编译keystore、jks签名证书
- 相互转换keystore、jks 签名证书
- 获取apk签名信息、抹除apk签名状态、重新签名apk
本来我只想简单记录一下如何帮apk进行签名,可是写着写着又写多了,我太难了 > < ~
- apk 相关准备
- cmd 签名基础
- 获取apk签名状态、信息
- 未签名状态
- 已签名信息
- 抹除apk签名状态、信息
- 顺利版
- 必成版
- 结果检验
- 重新签名apk
- 签名apk
- 签名成功
- 常见问题
- jarsigner 不是内部或外部命令,也不是可运行的程序
- jarsigner:无法打开 jar 文件:xxx.apk
Look Here:一定要注意使用cmd命令时涉及到对应路径时一定要输入正确,要么就直接cd到对应目录执行相关命令
在我的认知中,打签名包的方式主要有已下几种
- AndroidStudio打签名包(适合首次的签名包,二次打签名包的方式可能也有,但没去研究)
- 三方工具重新签名apk,不过这方面工具需自行查询,友情提示部分加固平台会提供签名工具
- jarsigner打签名包,需要配置jdk环境,然后通过cmd命令进行签名,相对以上俩者其功能广泛,可获取apk签名信息、抹除apk签名信息,重新apk签名
apk 相关准备
Look,一切开始之前,你需要准备以下文件和了解一些事情
- 确定apk存储路径: E:\outApk\test
- 未签名 before_test.apk(重新签名时会用到)
- 已签名 after_test.apk(抹除签名时会用)
- keystore、jks签名证书(重新签名时会用到)
我是记Blog时,临时创建了一个jks,证书信息如下 ~
cmd 签名基础
一切之始,从这段命令 jarsigner -h
讲起,翻译过来就是 java签名者 - 帮助
,我们首先需要熟悉基本命令与其含义才可以正式进行使用
cmd - jarsigner -h
获取以下命令信息
示例
C:\Users\Acer>jarsigner -h
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
用法: jarsigner [选项] jar-file 别名
jarsigner -verify [选项] jar-file [别名...]
[-keystore <url>] 密钥库位置
[-storepass <口令>] 用于密钥库完整性的口令
[-storetype <类型>] 密钥库类型
[-keypass <口令>] 私有密钥的口令 (如果不同)
[-certchain <文件>] 替代证书链文件的名称
[-sigfile <文件>] .SF/.DSA 文件的名称
[-signedjar <文件>] 已签名的 JAR 文件的名称
[-digestalg <算法>] 摘要算法的名称
[-sigalg <算法>] 签名算法的名称
[-verify] 验证已签名的 JAR 文件
[-verbose[:suboptions]] 签名/验证时输出详细信息。
子选项可以是 all, grouped 或 summary
[-certs] 输出详细信息和验证时显示证书
[-tsa <url>] 时间戳颁发机构的位置
[-tsacert <别名>] 时间戳颁发机构的公共密钥证书
[-tsapolicyid <oid>] 时间戳颁发机构的 TSAPolicyID
[-tsadigestalg <算法>] 时间戳请求中的摘要数据的算法
[-altsigner <类>] 替代的签名机制的类名
[-altsignerpath <路径列表>] 替代的签名机制的位置
[-internalsf] 在签名块内包含 .SF 文件
[-sectionsonly] 不计算整个清单的散列
[-protected] 密钥库具有受保护验证路径
[-providerName <名称>] 提供方名称
[-providerClass <类> 加密服务提供方的名称
[-providerArg <参数>]]... 主类文件和构造器参数
[-strict] 将警告视为错误
获取apk签名状态、信息
关键命令:jarsigner -verify -verbose -certs [apk存储路径信息]
未签名状态
cmd命令:jarsigner -verify -verbose -certs before_test.apk
已签名信息
cmd命令:jarsigner -verify -verbose -certs after_test.apk
获取到的签名信息太长了,图示分为俩部分 ~
- 图示 - 顶部
- 图示 - 尾部
抹除apk签名状态、信息
俩个版本的处理方式本质是一样的,之所以分俩个版本进行讲解,主要担心有的新手像我当年一样不知变通,所以稍微写的详细了一些 ~
顺利版
- 准备一个已签名的apk
- 将文件尾部后缀的apk改为zip(文件格式转换)
- 打开压缩包,删除META-INF
META-INF存放签名后的CERT和MANIFEST文件,用于识别软件的签名及版权
- 如何你第3步可以正常删除META-INF的话,那么直接将zip格式转回apk格式即可
必成版
- 准备一个已签名的apk
- 将文件尾部后缀的apk改为zip(文件格式转换)
- 解压之前apk转换后的zip文件
- 从解压后的文件中删除META-INF目录
- 重新将已删除META-INF的文件夹进行压缩,从而生成新的zip文件
- 进行压缩
- 将压缩好的文件从zip格式转为apk文件
结果检验
- 抹除签名信息前
- 抹除签名信息后
重新签名apk
准备工作,首先准备好需要签名的apk和签名证书
签名apk
cmd中常见的签名命令有俩种,一种是命令中不带密码进行签名,一种是直接带密码的命令进行签名
- 常见版
jarsigner -verbose -keystore {签名证书存放路径} -signedjar {签名后apk存放路径} {未签名的apk路径} {证书别名}
示例
jarsigner -verbose -keystore test.jks -signedjar test.apk before_test.apk test
签名成功
- 懒人版
jarsigner -verbose -keystore {签名证书存放路径} -storepass {签名证书密码} -signedjar {签名后文件存放路径} {未签名的文件路径} {您的证书别名}
示例
jarsigner -verbose -keystore test.jks -storepass 123123 -signedjar test.apk before_test.apk test
签名成功
签名成功
- 命令中指出签名成功
- 好吧,确实已经签名成功了
补充:Android打包时经常能看到V1、V2 包,其实它们对应的签名语句也不同
- V1签名(jarsigner方式)
jarsigner -verbose -keystore (签名地址) -signedjar (签名后的apk地址) (待签名apk地址) (别名)
- V2签名(apksigner方式)
apksigner sign --ks (签名地址) --ks-key-alias (别名) --out (签名后的apk地址) (待签名apk地址)
常见问题
其实很多的问题,都是因为粗心导致的 ~
jarsigner 不是内部或外部命令,也不是可运行的程序
一般报出这样的问题,基本都是你没有配置好jdk环境, 关于如何配置JDK环境,可以去我早期的一篇Blog看下,非常详细 ,如果懒得去的配置的话,就去jdk的bin目录下使用cmd命令,如下
cd C:\Program Files\Java\jdk1.8.0_45\bin
jarsigner:无法打开 jar 文件:xxx.apk
是不是不知道自己姿势哪不对,直接报错 ~
Look Here:好好检查下你的cmd命令和下面标记的一样吗?(一般都是由自己粗心造成)
jarsigner -verbose -keystore {签名证书存放路径} -signedjar {签名后apk存放路径} {未签名的apk路径} {证书别名}