android ota 版本校验,OTA升级签名校验简析

本文详细介绍了Android OTA升级包的签名验证流程,包括如何生成签名、使用sign_target_files_apks.py重签名APK、更新system和recovery签名,以及OTA包的校验过程。在签名校验阶段,公钥必须与待升级设备的公钥一致,以确保OTA包的完整性和安全性。
摘要由CSDN通过智能技术生成

1. 概要

如果进行过OTA升级的开发者,都或多或少有这样的疑问,如何确定该OTA升级包是可以信任的呢?这其中其实涉及到一个签名验证的流程。

2. 签名生成

在生成正规的固件时,一般会运行生成新key的脚本,并重新修改key中的信息。以网上常用的生成key的脚本为例:

#!/bin/sh

AUTH='/C=CN/ST=xxxx/L=xxxxx/O=xxxxxx/OU=xxxxx/CN=China/emailAddress=xxxxxxx@com'

openssl genrsa -3 -out $1.pem 2048

openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 \

-subj "$AUTH"

echo "Please enter the password for this key:"

openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -passout stdin

其中openssl通过genrsa标准命令生成私钥,默认大小为2048:

openssl genrsa -3 -out $1.pem 2048

生成私钥后,生成证书签署请求,即公钥:

openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 365 \

-subj "$AUTH"

-new: new request

-x509: output a x509 structure instead of a cert. req.该选项说明生成一个自签名的证书。

-keyfile: use the private key contained in file

-days: number of days a certificate generated by -x509 is valid for.

最后通过私钥pem文件生成PKCS8私钥文件

openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -passout stdin

也可以参考android原生的生成key的流程,位于android/development/tools下的make_key脚本i。

自此后,生成了一对公私钥用于签名校验。

3. sign_target_files_apks.py

3.1 对Apk进行重签名流程

sign_target_files_apks在本人之前的用法都局限于将targetfile里的apk进行重签名,其流程如下:

1.获取脚本输入参数

2.获取输入文件以及输出文件参数,读取misc_info文件

input_zip = zipfile.ZipFile(args[0], "r")

output_zip = zipfile.ZipFile(args[1], "w")

misc_info = common.LoadInfoDict(input_zip)

misc_info记录了一些参数,如下:

其中这里关注的是默认签名的路径:

default_system_dev_certificate=build/target/product/security/testkey

3.建立key映射

假如在调用脚本时未指定-d.-k参数,那么默认使用的正是系统自带的testkey。否则,将会映射到指定key目录下的Key

def BuildKeyMap(misc_info, key_mapping_options):

for s, d in key_mapping_options:

if s is None: # -d option

devkey = misc_info.get("default_system_dev_certificate",

"build/target/product/security/testkey")

devkeydir = os.path.dirname(devkey)

OPTIONS.key_map.update({

devkeydir + "/testkey": d + "/releasekey",

devkeydir + "/devkey": d + "/releasekey",

devkeydir + "/media": d + "/media",

devkeydir + "/shared": d + "/shared",

devkeydir + "/platform": d + "/platform",

})

else:

OPTIONS.key_map[s] = d

4.读取targetfile中的证书文件

apk_key_map = GetApkCerts(input_zip)

GetApkCerts的实现如下,其实质是读取了targetfile中/META/apkcerts.txt文件

def GetApkCerts(tf_zip):

certmap = common.ReadApkCerts(tf_zip)

# apply the key remapping to the contents of the file

for apk, cert in certmap.iteritems():

certmap[apk] = OPTIONS.key_map.get(cert, cert)

# apply all the -e options, overriding anything in the file

for apk, cert in OPTIONS.extra_apks.iteritems():

if not cert:

cert = "PRESIGNED"

certmap[apk] = OPTIONS.key_map.get(cert, cert)

return certmap

def ReadApkCerts(tf_zip):

"""Given a target_files ZipFile, parse the META/apkcerts.txt file

and return a {package: cert} dict."""

certmap = {}

for line in tf_zip.read("META/apkcerts.txt").split("\n"):

line = line.strip()

if not line:

continue

m = re.match(r'^name="(.*)"\s+certificate="(.*)"\s+'

r'private_key="(.*)"$', line)

if m:

name, cert, privkey = m.groups()

public_key_suffix_len = len(OPTIONS.public_key_suffix)

private_key_suffix_len = len(OPTIONS.private_key_suffix)

if cert in SPECIAL_CERT_STRINGS and not privkey:

certmap[name] = cert

elif (cert.endswith(OPTIONS.public_key_suffix) and

privkey.endswith(OPTIONS.private_key_suffix) and

cert[:-public_key_suffix_len] == privkey[:-private_key_suffix_len]):

certmap[name] = cert[:-public_key_suffix_len]

else:

raise ValueError("failed to parse line from apkcerts.txt:\n" + line)

return certmap

在这里可以分析下apkcerts文件,其内容格式如下:

name="RecoveryLocalizer.apk" certificate="build/target/product/security/testkey.x509.pem" private_key="build/target/product/security/testkey.pk8"

name="CtsVerifier.apk" certificate="build/target/product/security/testkey.x509.pem" private_key="build/target/product/security/testkey.pk8"<

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值