一种对AndroidAPK增加自定义签名的方法与流程

文档序号:15845097发布日期:2018-11-07 08:55阅读:558来源:国知局
一种对Android APK增加自定义签名的方法与流程

本发明涉及签名和验签的方法,特别涉及android中用于在apk完整性校验机制中添加自定义签名验签的方法。

背景技术

在android平台上运行的每个应用都必须有开发者签名,在应用商店或android设备上的软件包安装程序会拒绝没有获得签名就尝试安装的应用。

在android上,应用签名是将应用放入沙盒的第一步。签名可确保不同应用使用不同的用户id,从而确保一个应用无法访问其他应用数据,除通过明确定义进程间通信(ipc)访问。

android应用目前可由第三方(原始设备制造商(oem)、运营商、其他应用市场)进行签名,也可自签名,android提供了使用自签名证书进行代码签名的功能,应用并非必须由核心机构签名,目前并不对应用证书进行电子商务认证中心(ca)认证。

目前android支持两种签名方案,一种是jar签名,即常说的v1(signedjarfile)签名方案(参考相关链接:https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#signed_jar_file),v1签名方案缺点在于无法保证apk的完整性,例如apk在没有v2签名(参考相关链接https://source.android.google.cn/security/apksigning/v2)的情况下,其格式为标准的zip格式,修改zip的元数据并不被识别,即不被v1签名所保护。在android7.0中引入了apk签名v2(v2签名方案),该方案直接对apk的内容进行哈希处理和签名,并将“apk签名分块”插入apk中,该方案对zip元数据的修改将会导致apk签名作废,不仅加快了校验速度,并增强了完整性校验。因为apk的v2签名方案是在androuid7.0(nought)中引入的,为了兼容android6.0(marshmallow)及更低的版本安装,多数情况下将采用v1+v2的签名方案,即先使用v1签名对apk进行签名,然后再使用v2签名对其进行签名。

目前上述的签名方案中,首先是不对应用证书进行ca认证,其次仅支持部分签名算法id,且完全不支持我国自主研制的sm2算法签名,为此,申请人进行了有益的探索和尝试,找到了解决上述问题的办法,下面将要介绍的技术方案便是在这种背景下产生的。



技术实现要素:

本发明的目的之一在于针对现有android签名方案所存在的不足而提供一种对androidapk增加自定义签名的方法,该方法提供一种不影响原apk的签名验签,添加额外的自定义签名,并在签名中携带签名证书用以进行ca认证,并提供更加全面的算法支持,例如sm3withsm2,sha3-256withrsa等。并考虑到仅v1签名,以及携带v2签名的不同应用场景,提供兼容的解决方案。

本发明所解决的技术问题可以采用以下技术方案来实现:

一种对androidapk增加自定义签名的方法,包括如下步骤:

步骤1,获取整个apk文件作为字节流读入;

步骤2,不为签名操作,跳过该步骤,如果为签名操作,根据步骤1获取的apk字节流做不带原文的p7签名处理,获得以原apk字节流作为原文的p7签名;

步骤3,apk为标准zip格式,获取对应的中央目录记录的结尾(eocd)块;

步骤4,根据步骤1获取的apk字节流,判断签名方案,如果仅有v1签名方案则进入步骤5,如果存在v2签名方案则进入步骤8;

步骤5,如果为签名操作,进入步骤6,如果为验签操作,进入步骤7;

步骤6,根据步骤3获得的中央目录记录的结尾块,修改其中注释段大小,并在注释段内容中添加对应自定义“id-值“对,id为自定义id,值为步骤2获取到p7签名块大小,以unit32值来标识该大小,后跟p7签名数据块;进入步骤14;

步骤7,根据步骤3获得的中央目录记录的结尾块,获取到注释段大小,根据注释段大小,查询自定义id,紧跟自定义id的内容为p7签名数据大小,根据p7签名数据大小读入p7签名数据;还原注释段大小,删除添加的自定义数据,得到原先apk数据作为原文,进行p7验签操作,进入步骤15;

步骤8,在存在v2签名方案的情况下,apk在标准zip格式上添加了一个“apk签名分块”,根据步骤3获取的中央目录记录的结尾块,通过中央目录记录的结尾块中记录的核心中央目录偏移可以找到apksigningblock;

步骤9,如果为签名操作,进入步骤10,如果为验签操作,进入步骤12;

步骤10,根据步骤8获取的apksigningblock,因为v2签名对apk完整性加入了校验,但是校验内容仅包括contentsofzipentries,centraldirectory,endofcentraldirectory三个部分与apksigningblock中的signeddata部分,保护apksigningblock中的signeddata是为了防止删除安全系数高的签名的攻击,但是并不影响apksigningblock中其他字段的变动,根据官方文档在解译该分块时,应忽略id未知的“id-值”对,我们可以通过插入对应自定义“id-值”对到对应“id-值”序列位置,id为自定义id,值为步骤2获取到p7签名块大小,以unit32值来标识该大小,后跟与仅v1签名方案保持一致格式的p7签名数据块;

步骤11,根据步骤10修改后的signingapkblock计算出新的核心中央目录偏移量,并根据步骤3获的eocd块,将eocd块中记录的核心中央目录偏移修改为现有最新的偏移量;进入步骤14;

步骤12,根据步骤8获取的apksigningblock,根据官方定义结构可以查询到“id-值”对的位置,然后跳过官方“apk签名方案v2分块”即为自定id位置,判断id值是否为自定义id,防止其他插入数据引发异常,获取p7签名数据大小,后紧跟p7签名数据;

步骤13,根据步骤12获得的apksigningblock,删除自定义部分内容,并将eocd块中记录的核心中央目录偏移修改为删除自定义字段后核心中央目录偏移,以还原的apk字节流作为原文,进行p7签名的验签操作;进入步骤15;

步骤14,将步骤6与步骤11生成的新apk的字节流写入apk文件中。新的apk即包含自定义“id-值”对的apk;

步骤15,如果验签结果为true,则对应额外签名验证成功,如果验签结果为false,则对应额外签名验证失败。

在本发明的一个优选实施例中,所述步骤4中,所述v2签名方案为包含仅有v2签名方案以及v1,v2签名方案同时存在良好总情况。

在本发明的一个优选实施例中,所述步骤6中,所述注释段大小仅2字节,数据不超过64k,unit32占4字节,可标识近4g大小数据。

本发明的一个优选实施例中,所述步骤6中,所述p7签名数据块带签名证书用于ca认证,不带原文,以整个apk字节流作为原文。

由于采用了如上的技术方案,本发明与现有技术相比,具有以下优点:

1.将整个使用官方签名后apk的字节流作为原文,进行p7签名操作(带签名证书用于ca认证,不带原文,已整个apk字节流作为原文,带原文数据过大),之后将产生的p7签名数据按照自定义id(unit32)+p7签名长度(unit32)+p7签名数据结构在仅v1签名签名方案时插入eocd块中注释段,在包含v2签名方案时插入apksigningblock块中的“id-值”对中。

2.对整个apk的字节流进行处理:将整个apk字节流进行处理,进一步扩大了原apk的完整性校验,原apk在仅v1签名方案是,可以通过该方案对zip元数据进行保护,当修改了对应zip元数据,将会在验签过程失败,在包含v2签名方案中,进一步增强了完整性校验,再添加额外签名后,无论在apk的字节流中做任何处理,均会被新增签名所校验。并且在基础上,提供比官方更加全面的算法支持,不仅局限于官方的7种签名算法,支持多种签名算法,包括我国自主研制的sm2算法。

3.使用p7签名进行签名验签:p7结构中不带原文,因为原文为整个apk的字节流,数据可能比较大,影响apk体积,且仅v1方案中注释段大小必须限制在64k,所以采用不带原文的p7签名方式,p7签名数据中带签名证书,以提供对应用证书进行ca的认证,更加有效地保证apk的开发者签名的来源。

4.签名数据按照自定义id(unit32)+p7签名长度(unit32)+p7签名数据:签名数据按照自定义id(unit32)+p7签名长度(unit32)+p7签名数据,可以保证再有其他id存在的情况下,可以找到我方定义的结构,并获取对应的p7签名数据,在仅v1签名方案中计算eocd注释段大小以及包含v2签名方案下计算eocd中核心中央目录的偏移量。

附图说明

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1是本发明的一种对androidapk增加自定义签名的方法的流程图。

图2为本发明的对apk添加额外签名流程图。

图3是本发明的对apk添加的额外签名进行验签流程图。

具体实施方式

为了使本发明实现的技术手段、创作特征、达成目的与功效易于明白了解,下面结合具体图示,进一步阐述本发明。

参见图1,对apk添加额外签名的流程说明:

签名步骤1:获取apk字节流。

签名步骤2:对步骤1获取的apk字节流做一次p7签名处理(带签名证书用于ca认证,不带原文,已整个apk字节流作为原文,带原文数据过大)。

签名步骤3:获取apk中的eocd块。

签名步骤4:判断是仅v1签名方案还是包含v2签名方案。如果是仅v1签名方案进入步骤5,如果是包含v2签名方案进入步骤6。

签名步骤5:在eocd块的注释内容中添加自定义id(unit32)+p7签名数据长度(unit32)+p7签名数据,修改eocd块注释大小字段为现注释大小+自定义内容大小。进入步骤7。

签名步骤6:根据eocd块中核心中央目录偏移查询到apksigningblock位置,向其中“id-值”对中插入id为自定义id(unit32),值为p7签名数据长度(unit32)+p7签名数据的数据内容,并修改eocd块中核心中央目录偏移为原偏移+添加数据的长度。

签名步骤7:输出对应修改后的字节流到新的apk文件中。

参见图2,对apk添加的额外签名进行验签的流程说明:

验签步骤1:获取apk字节流。

验签步骤2:获取apk中eocd块。

验签步骤3:判断是仅v1签名方案还是包含v2签名方案。如果是仅v1签名方案进入步骤4,如果是包含v2签名方案进入步骤6。

验签步骤4:在eocd注释段中查找对应自定id,若未找到则直接判定验签失败,找到对应id,id后紧跟为p7签名数据大小,根据大小可以获取对应p7签名数据。

验签步骤5:将eocd中注释段添加自定义内容删除,并将对应eocd注释段大小字段更新为现大小-自定义内容大小。进入步骤9。

验签步骤6:通过eocd块中记录的核心中央目录偏移,获取apksigningblock块。

验签步骤7:在apksigningblcok中查找对应id,若未找到则直接判定验签失败,找到对应id,id后紧跟为p7签名数据大小,根据大小可以获取对应p7签名数据(格式与仅v1情况下保持一致)。

验签步骤8:将自定义“id-值”对从apksigningblock中删除,并修改eocd块中核心中央目录偏移为现偏移-自定义内容大小。

验签步骤9:将还原的apk字节流作为原文,与p7签名数据进行验签操作。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1