Sign update.zip for MiRecovery

  • fennng 
小米盒子增强版成功降级后, 又可以Root了. Root了以后我便想安装其它的版本. 因为降级后的版本 1.3.112d是一个不可以升级的版本, 我怕1.3是不是有点太老, 升到1.4会不会好些?
于是我便从这里下载了一个被修改过的小米recovery.
可是我却发现它并不能用, 因为我想用他刷一个石头论坛以前下的小米1.3.72的固件的时候,刷失败了. 显示签名错误. 我明明记得我是用那个固件从石头的系统恢复回小米系统的.
于是我从石头的刷机工具里面提取了recovery, 并成功的刷入了1.3.72的固件包. 所以我就开始以为那个mirecovery 跟本没用.
但是后来,我又在这个页面找到了可以用这个recovery 刷的固件包
于是我就纳闷了, 怎么这些包又可以刷了, 这些包也不是官方包呀! 后来我发现, 原来1.3.72那个固件没有签名, 所以刷不了. 而石头中提取的recovery好像只能刷没签名的包,签了名反而不能刷. 所以就是说, 只要把包签名了, 这个mirecovery 还是能用的.
今天正好想试试自己打包update.zip 文件.
开始也没有查资料, 先用现有的知识做个签名.
先生成一个keystore
keytool -genkey -v -keystore recovery.keystore -alias feng_recovery -keyalg RSA -keysize 2048 -validity 10000
 
然后用jarsigner 签名
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore recovery.keystore update.zip feng_recovery
Enter Passphrase for keystore:
   adding: META-INF/MANIFEST.MF
   adding: META-INF/FENG_REC.SF
   adding: META-INF/FENG_REC.RSA
   adding: system/
  signing: system/test.txt
jar signed.
签完名得到一个这样的结构
拿去recovery试,  直接就废.

E:footer is wrong
E:signature verification failed

 

于是上网找到这个教程.
用openssl 来生成公私钥
openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -out request.pem
openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt
​​
用 signapk.jar 来签名, 而不是jarsigner
java -jar signapk.jar certificate.pem key.pk8 update.zip signed-update.zip
这次的结构对了, 因为CERT.RSA, CERT.SF 的文件名对了, 跟其它我用过的包一样, 说明 signapk.jar 用对了.
再拿去试, 还是一样的错误.
然后我查了一个可以用的update.zip包的签名, 用的是signapk.jar 自带的那个testkey.

Use jarsigner, I found out it’s using the testkey come with SignApk.jar
jarsigner -verify -verbose -certs  update.zip
Key for signed_update_1.3.102.2024.zip
 
      X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
      [certificate is valid from 29/02/08 2:33 PM to 17/07/35 1:33 PM]
      [CertPath not validated: Path does not chain with any of the trust anchors]
好吧,我也用这个key 好了.
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip signed-update.zip
 
然后查一下, 查出来的信息一模一样了.
 
 
X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
      [certificate is valid from 29/02/08 2:33 PM to 17/07/35 1:33 PM]
      [CertPath not validated: Path does not chain with any of the trust anchors]
去试试, 我X, 还是这个错误, 有没有搞错,我到底哪里没弄对….
Still got the following error.
E:footer is wrong
E:signature verification failed
Installation aborted.
然后有人说 footer is wrong 是因为 zip 文件没有comment. 不会吧….
Someone mentioned that footer is wrong is caused by the zip comment.
查一下可用的那个包, 还真有comment
fengnz@mac:~/Downloads > unzip -z signed_ota-fixer_1.3.102.2024
Archive:  signed_ota-fixer_1.3.102.2024.zip
signed by jBART (BurgerZ)
而我做的包没有
There is no comment for my zip file
fengnz@mac:~/Documents/recovery_learn > unzip -z signed-update.zip
Archive:  signed-update.zip

行, 小事,我也加comment
fengnz@mac:~/Documents/recovery_learn > zip -z signed-update.zip
enter new zip file comment (end with .):
Signed By YuFeng Deng.
.
fengnz@mac:~/Documents/recovery_learn > unzip -z signed-update.zip
Archive:  signed-update.zip
Signed By YuFeng Deng.
加完后…还是一样…
Still same error
好吧, 我注意到它是用jBART签的名, 所以下载个jBART来用


I found that the file it created is 2K bigger than my one
签好后, 查一下comment, 跟可用的那个包一样了

fengnz@mac:~/Documents/recovery_learn > unzip -z signed_update.zip
Archive:  signed_update.zip
signed by jBART (BurgerZ)
再查一下签名, 对, 用的就是 那个testkey
jarsigner -verify -verbose -certs signed_update.zip
   X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
      [certificate is valid from 29/02/08 2:33 PM to 17/07/35 1:33 PM]
      [CertPath not validated: Path does not chain with any of the trust anchors]

这回拿去试, 居然成功了!!!

Now Success
到底哪里不一样? 我也是这么签的呀? 为什么它签出来会大2K?
What’s the difference between jBART sign and my own sign? The same keys are used?
我之前如果签名不对, 出的错误是”Fail to verify whole-file signature”. 这回没有这么说, 所以说明whole-file signature是好的. 只是footer 错了. 那什么是footer?
It doesn’t say “Fail to verify whole-file signature”. Means the whole-file signature is Ok. The error is caused by the footer. What’s the footer here?
然后我发现了这篇文章. 明白footer其实是在查这个zip 包的倒数第三个和第四个字节. 如果这个字节不对, 说明没有whole-file signature, 所以不是说whole-file signagure是好的, 而是跟本没有, 所以不查, footer 直接fail.
 
The recovery program check the footer to make sure the whole-file signature is existing. If not, it doesn’t go future and throw signature failure.
 
 

 
然后发现其实签名还分两种, 一种是对压缩包里面的每个文件进行签名, 另一种是对整个压缩包签名, 就是所谓的whole-file signaure. 
 
signapk.jar 默认不做whole-file signature, 需要加 -w 参数. 
 
可是我的signapk.jar 不支持这个参数呀, 我早就查过了.
 
 
fengnz@mac:~/Downloads > java -jar signapk.jar
Usage: signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar
There is not -w option
然后我只好上网继续找支持 -w 的signapk.jar
The first version I found was a 7.2K signapk.jar
最后终于找到了…
I then searched hard on the internet and finally found a 9K signapk.jar which supports -w option
这个有 -w 参数耶
fengnz@mac:~/Documents/recovery_learn > java -jar signapk.jar
Usage: signapk [-w] publickey.x509[.pem] privatekey.pk8 input.jar output.jar
然后
 java -jar signapk.jar -w testkey.x509.pem testkey.pk8 update.zip signed-update.zip
 
成功了, 签名来的文件大小和 jBART 一样大. 试了一下, 可以用.
 
然后我试了下最开始自己用openssl 生成的key, 不行. 一定要用testkey.
 
好了…花了好几个小时, 终于解开了这个迷团. 上网查, 大家都说是因为你自签名的包不能用在stock recovery. 就没有人说到是因为忘了使用-w 参数而没有 whole-file signature. 

《Sign update.zip for MiRecovery》有1个想法

发表评论

您的电子邮箱地址不会被公开。