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,一切开始之前,你需要准备以下文件和了解一些事情

androidkill 移除签名校验 apk去除签名效验_抹除apk签名状态

  • 确定apk存储路径: E:\outApk\test
  • 未签名 before_test.apk(重新签名时会用到)
  • 已签名 after_test.apk(抹除签名时会用)
  • keystore、jks签名证书(重新签名时会用到)

我是记Blog时,临时创建了一个jks,证书信息如下 ~

androidkill 移除签名校验 apk去除签名效验_签名apk_02


cmd 签名基础

一切之始,从这段命令 jarsigner -h讲起,翻译过来就是 java签名者 - 帮助 ,我们首先需要熟悉基本命令与其含义才可以正式进行使用

cmd - jarsigner -h 获取以下命令信息

androidkill 移除签名校验 apk去除签名效验_获取apk签名信息_03


示例

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

androidkill 移除签名校验 apk去除签名效验_签名apk_04

已签名信息

cmd命令:jarsigner -verify -verbose -certs after_test.apk

获取到的签名信息太长了,图示分为俩部分 ~

  • 图示 - 顶部
  • 图示 - 尾部

抹除apk签名状态、信息

俩个版本的处理方式本质是一样的,之所以分俩个版本进行讲解,主要担心有的新手像我当年一样不知变通,所以稍微写的详细了一些 ~

顺利版
  1. 准备一个已签名的apk
  2. 将文件尾部后缀的apk改为zip(文件格式转换)
  3. 打开压缩包,删除META-INF
    META-INF存放签名后的CERT和MANIFEST文件,用于识别软件的签名及版权
  4. 如何你第3步可以正常删除META-INF的话,那么直接将zip格式转回apk格式即可
必成版
  1. 准备一个已签名的apk
  2. 将文件尾部后缀的apk改为zip(文件格式转换)
  3. 解压之前apk转换后的zip文件
  4. 从解压后的文件中删除META-INF目录
  5. 重新将已删除META-INF的文件夹进行压缩,从而生成新的zip文件
  6. 进行压缩
  7. 将压缩好的文件从zip格式转为apk文件
结果检验
  • 抹除签名信息前
  • androidkill 移除签名校验 apk去除签名效验_抹除apk签名状态_05

  • 抹除签名信息后
  • androidkill 移除签名校验 apk去除签名效验_androidkill 移除签名校验_06


重新签名apk

准备工作,首先准备好需要签名的apk和签名证书

androidkill 移除签名校验 apk去除签名效验_获取apk签名信息_07

签名apk

cmd中常见的签名命令有俩种,一种是命令中不带密码进行签名,一种是直接带密码的命令进行签名

  • 常见版

jarsigner -verbose -keystore {签名证书存放路径} -signedjar {签名后apk存放路径} {未签名的apk路径} {证书别名}

示例

jarsigner -verbose -keystore test.jks -signedjar test.apk before_test.apk test

签名成功

androidkill 移除签名校验 apk去除签名效验_Android_08

  • 懒人版

jarsigner -verbose -keystore {签名证书存放路径} -storepass {签名证书密码} -signedjar {签名后文件存放路径} {未签名的文件路径} {您的证书别名}

示例

jarsigner -verbose -keystore test.jks -storepass 123123 -signedjar test.apk before_test.apk test

签名成功

androidkill 移除签名校验 apk去除签名效验_获取apk签名信息_09

签名成功
  • 命令中指出签名成功
  • 好吧,确实已经签名成功了

补充: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

是不是不知道自己姿势哪不对,直接报错 ~

androidkill 移除签名校验 apk去除签名效验_androidkill 移除签名校验_10


Look Here:好好检查下你的cmd命令和下面标记的一样吗?(一般都是由自己粗心造成)

jarsigner -verbose -keystore {签名证书存放路径} -signedjar {签名后apk存放路径} {未签名的apk路径} {证书别名}