Ronny 's Blog
坚持!
Toggle navigation
Ronny 's Blog
Home
About Me
Archives
Tags
04--制作自己的签名key,以及不同keytype的签名方法
2020-01-03 17:26:21
271
0
0
haiyang
本篇文章主要介绍如何制作自己的签名key。 # 一、使用keytool工具生成数字证书 ## 1、制作证书keystore > keytool -genkey -keystore kbbs.keystore -alias kbbs -keyalg RSA -validity 20000 说明: 1)keytool是工具名称,-genkey意味着执行的是生成数字证书操作,-v表示将生成证书的详细信息打印出来,显示在dos窗口中; 2) -alias ronny表示证书的别名为“ ronny”,当然可以不和上面的文件名一样; 3)-keyalg RSA 表示生成密钥文件所采用的算法为RSA; 4)-validity 20000 表示该数字证书的有效期为20000天,意味着20000天之后该证书将失效 5)-keystore ronny.keystore 表示生成的数字证书的文件名为“ronny.keystore ”; 在执行上面的命令生成数字证书文件时,会提示你输入一些信息,包括证书的密码,示例如下: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/generatorkeystore.png) 密钥库口令:kbbs962457, kbbs的密钥口令:同密码库口令,因为如果不一致在最后生成pk8和pem过程中会报错。 这样keystore就制作完成了,有了它就可以用它做成密钥对,所以这个keystore很重要。有了密钥对也可以转成相应的keystore。如果私钥也被别人搞到了那就没有什么安全可言了。所以keystore不能给别人,且要设置密钥库口令。这样别人获取了keystore也做不了key,用keystore直接签名同样需要密码。 ## 2、直接用keystore签名 使用jarsigner工具和刚刚制作的数字证书为Android应用程序签名,注意要输入别名(这个直接在jdk中,配好jdk就能用了) > jarsigner -verbose -keystore ~/key/kbbs.keystore -signedjar app-release_signed.apk app-release-unsigned.apk kbbs -digestalg SHA1 -sigfile CERT `keystore转成pk8后用signapk.jar签名, 发现里面的摘要的算法名称是SHA1 ,而我生成的keystore签名算法名称: SHA256withRSA,在签名时对摘要算法采取的是SHA256,所以我如果想和signapk.jar的签名尽量保持一致,那需要增加-digestalg来指定摘要算法的名称,我这里需要增加 -digestalg SHA1,另外发现keystore签完的apk中RSA和SF文件的名称都是kbbs,而不是CERT,所以我为了和signapk.jar尽量保持一直所以我增加了参数-sigfile CERT来指定.SF/.DSA 文件的名称为CERT` 说明: 1)jarsigner是工具名称,-verbose表示将签名过程中的详细信息打印出来,显示在dos窗口中; 2)-keystore ~/key/kbbs.keystore 表示签名所使用的数字证书所在位置,这里有写路径,这里也可以直接写kbbs.keystore,则表示在当前目录下; 3)-signedjar app-release_signed.apk app-release-unsigned.apk 表示给app-release-unsigned.apk文件签名,签名后的文件名称为app-release_signed.apk; 4)最后面的kbbs 表示证书的别名,对应于生成数字证书时-alias参数后面的名称 为了方便我一般都写一个shell脚本signkeystore.sh对app签名: ```shell ####signkeystore.sh内容######## #!/bin/bash -xv jarsigner -verbose -keystore kbbs.keystore -signedjar $2 $1 kbbs -digestalg SHA1 -sigfile CERT ``` 使用方法: ```shell ./signkeystore.sh app-unsigned.apk app-signed.apk ``` `注意:这时签名过程中会让输入密钥库的密码短语:如果条目密码和密钥库的密码不一致还会让输入条目密码,这个过程有密码输入错误则无法签名,签名正确则可以正常得到签名的app ,如下图:` ![](http://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/keystore_sign_app.png) 图中报了一个warning: `未提供 -tsa 或 -tsacert, 此 jar 没有时间戳。如果没有时间戳, 则在签名者证书的到期日期 (2072-09-30) 或以后的任何撤销日期之后, 用户可能无法验证此 jar。` 警告的话本身对签名没有影响,但是总感觉怪怪的,要想去掉这个警告只要在命令上再加上` -tsa https://timestamp.geotrust.com/tsa `就可以了,但是可能网络的问题,可能需要翻墙,无法得到response。 # 二、用keystore转换成pk8格式的私钥和pem的公钥,用signapk.jar来签名 ## 1、转换成pk8、pem密钥对 - 1) 转换key的格式 执行命令: ```shell keytool -importkeystore -srckeystore kbbs.keystore -destkeystore kbbs.p12 -srcstoretype jks -deststoretype pkcs12 ``` 控制台会提示输出kbbs.p12的密码以及kbbs.keystore的密码,输入正确之后将会生成kbbs.p12文件。如图所示: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/keystorestopkcs12.png) - 2) 将pkcs12格式的key dump为可直接阅读的文本 执行命令: ```shell openssl pkcs12 -in kbbs.p12 -nodes -out kbbs.rsa.pem ``` dump过程中也会提示输入密码,正确输入之后可阅读的token会存储在kbbs.rsa.pem中 说明:pkcs12格式的 -in 输入文件,-out 是输出文件 ,-nodes是不加密私钥,生成的文件kbbs.rsa.pem包含rsa类型的公钥和私钥和ssh-genkey差不多,只是它直接都导在一个文件里了,如下图所示:(key内容不截出来了) ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/dump_pkcs12.png) - 3) 提取 用文本编辑器打开kbbs.rsa.pem,将从 -----BEGIN PRIVATE KEY----- 到 -----END PRIVATE KEY----- 这一段(包含这两个tag)的文本复制出来,新建为文件kbbs_private.rsa.pem 将从 -----BEGIN CERTIFICATE----- 到 -----END CERTIFICATE----- 这一段(包含这两个tag)的文本复制出来,新建为文件kbbs.x509.pem (签名时用到的公钥) `即:(将kbbs.rsa.pem公私钥分别提出来放在两个文件kbbs_private.rsa.pem和里kbbs.x509.pem)这时私钥还是明文的,能看见内容` - 4) 转换,生成pk8格式的私钥 ```shell openssl pkcs8 -topk8 -outform DER -in kbbs_private.rsa.pem -inform PEM -out kbbs_private.pk8 -nocrypt ``` 说明: ①不要忘记加-topk8参数 ②`-nocrypte 用非加密私钥,就是生成的私钥不再加密,也就是在用私钥签名的时候不用在输入密码, 如果不加-nocrypte会提示设置加密密码,然后在签名的时候用.` 如图所示(加-nocrypt参数转换): ![加-nocrypt参数转换](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/switchpk8_and_signapk.png) 如图所示(不加-nocrypt参数转换,需要设置密码:eg设置:6628628,然后在签名时输入密码): ![不加-nocrypt参数转换1](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/switchpk8_hasnomaram_nocrypt1.png) ![不加-nocrypt参数转换2](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/switchpk8_hasnomaram_nocrypt2.png) 防止搞混建议新建目录`Certificate`把密钥对`kbbs_private.pk8`(私钥)和`kbbs.x509.pem`(公钥)放进去。 这个生成的my_private.pk8就是签名时用到的私钥 **`将明文私钥转成二进制,看不到具体内容。(那私钥也不能公开!)`** **密钥对就制作完成了,x509里面的公钥就那样就完了。** ## 2、对apk签名 ```shell java -jar signapk.jar kbbs.x509.pem kbbs_private.pk8 app_unsigned.apk app_signed.apk ``` # 三、密钥对转成keystore,供android studio用 `适用情况`:如果有密钥对--pk8格式的私钥和pem的公钥如何转换成keystore,好用keystore来签名(Android Studio) 整个步骤基本和keystore转pk8相反,很好理解 - 1) 把pk8转换成pk12格式(DER TO PEM,转成类似rsa私钥形式,可以看到) ```shell openssl pkcs8 -in kbbs_private.pk8 -inform DER -outform PEM -out kbbs_private.rsa.pem -nocrypt ``` 如图所示: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/pk8switchDERtoPEM.png) - 2) 生成pk12的密钥文件(把公私钥合并成一个文件) ```shell openssl pkcs12 -export -in kbbs.x509.pem -inkey kbbs_private.rsa.pem -out kbbs.p12 -name kbbs ``` ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/pemkeypairswitchpk12.png) - 3)pk12转成keystore ```shell keytool -importkeystore -srckeystore kbbs.p12 -destkeystore kbbs.keystore -srcstoretype pkcs12 -deststoretype jks ``` ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/pkcs12switchkeystore.png) 转换成keystore后`keytool -v -list -keystore kbbs.keystore`查看key的详细内容,发现和以前的初始keystore一样,文件大小也一样,但是两个keystore文件的MD5sum值不一样,我的理解是还原后的keystore应该与我们的原始keystore文件MD5值一样,这地方有些差异。 # ISSUE: - 1 JKS导出的P12无法导入keychain或转换成pem问题:Error outputting keys and certificates fixed:密码库和条目密码改成一致这个问题就好了。不一致就不行,不管密码是否简单。 - 2 用keystore手动签名时警告: 未提供 -tsa 或 -tsacert, 此 jar 没有时间戳。如果没有时间戳, 则在签名者证书的到期 fixed:在命令上再加上 -tsa https://timestamp.geotrust.com/tsa 就可以了,网站可能被墙,所以我尝试出错提示:jarsigner: 无法对 jar 进行签名: 时间戳颁发机构没有响应。如果要从防火墙后面连接...... # 重点:keystore和pk8的签名差异 - ①制作完自己的keystore和pk8密钥对后对同一个app做了签名,解开后用bcompare比较了一下发现META-INF中的摘要不一样,pk8签的摘要算法用的是SHA1,keystore签的用的是SHA256。如图所示: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/jiamizhaiyaovs1.png) 然后我先用pk8签了一个helloworld应用,安装后运行正常显示helloworld, 改成helloworld2 编译后用keystore签名,同时版本号加1,adb install -r app-signed.apk,结果也可以正常安装。我的android系统版本是4.4.4. 如果想keystore和pk8签出来的摘要文件的摘要值一样,那我们可以在keystore中指定签名的摘要算法为SHA1 可以写成一个脚本signapp_for_keystore.sh: ```shell #!/bin/bash -xv jarsigner -verbose -keystore kbbs.keystore -signedjar $2 $1 kbbs -digestalg SHA1 # [-signedjar <文件>] 已签名的 JAR 文件的名称 。$2是已签名的app,$1为未签名 ``` 使用方法: ``` ./signapp_for_keystore.sh app-unsigned.apk app-signed.apk ``` 加了`-digestalg SHA1`之后keystore和pk8的签名摘要值一致,如图所示: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/jiamizhaiyaovs2.png) - ②虽然我的可以正常安装,但是网上查资料的时候看到有人遇到无法安装的情况: > Android应用签名命令后提示您的应用签名算法采用“SHA256withRSA”,在部分4.2一下安卓版本的手机上不能安装的 解决方案:在命令中加上 :-sigalg SHA1withRSA -digestalg SHA1 - ③在制作keystore的时候发现有-sigalg选项,(可以`keytool -genkey --help`查看) 就是在制作keystore的时候参数-sigalg <sigalg> 即签名算法名称,公司的eng是 # 验证v1 v2签名 需要用到/home/ronny/Android/Sdk/build-tools/25.0.2/lib下的apksigner.jar。同时需要jdk1.8环境 命令: ```shell cd /home/ronny/Android/Sdk/build-tools/25.0.2/lib java -jar apksigner.jar verify -v $path../name.apk ``` 如下图所示: ![](https://kbbs.oss-cn-shanghai.aliyuncs.com/journal/appsign/verify_appv1v2signed.png) # SUMMARY: ①keystore转成pk8流程是keystore转成p12格式,然后p12格式看不到key的明码,所以我们有把kbbs.p12中的密钥信息dump出来,输出到kbbs.p12kbbs.rsa.pem中,然后kbbs.rsa.pem中可以看到私钥和公钥,公钥内容直接粘贴,新建一个kbbs.x509.pem文件把公钥粘进去,公钥就完成了。然后私钥粘贴在新建的文件kbbs_private.rsa.pem中,这时kbbs_private.rsa.pem中的私钥是明文的,要转换成pk8格式。然后就可以用了。 ②pk8转成keystore的流程正好相反,首先pk8私钥转成明文的kbbs_private.rsa.pem,然后明文的私钥kbbs_private.rsa.pem和公钥kbbs.x509.pem转成pk12格式文件kbbs.pk12,然后pk12转成keystore. 参考文章: blog.csdn.net/darkengine/article/details/42773745 blog.csdn.net/lyankj/article/details/51840138 blog.csdn.net/sendwave/article/details/73699340
Pre:
46--logcat的使用大全(自我总结)
Next:
03--html基础之各种标签详解
0
likes
271
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Submit
我的网站不支持评论,拒绝网络暴力,不造谣、不信谣、不传谣,传递正能量。
0
comments
More...
Table of content