对apk包进行数字签名提升传输安全性

前言

这段时间有一个对web app进行签名验证的一个需求,为了确保所下载的apk包来自于咱们所信任的服务器,防止请求被劫持或者替换,因为暂时仍是使用http协议在上https以前有一个过渡期,因此不得不考虑传输安全,毕竟http就是在整个网络上"裸奔"。前端

数字签名

作这个以前咱们首先得了解数字签名究竟是什么,在作这个验签以前我也一直是处于据说过的状态中,因此作这个任务以前花了一点时间去了解一下。简单说数字签名只作一件事情,就是证实这个内容必定来自于某人,为何呢?由于使用私钥进行签名,所以只有他本身能生成本身的签名(私钥被盗不算)。git

说这个数字签名以前咱们首先简单提一下密码学的知识,加密方法大体分为两类:对称加密(加密和解密都使用一套密钥)、非对称加密(有两套密钥,一套私钥、一套公钥,私钥只有本身知道,公钥能够给其余人;通常发送方用公钥加密发送消息,而只有本身可以用私钥进行解密,以此达到安全传输消息的目的;而签名通常使用私钥,用公钥进行验证签名)。可是我在实现个人过程当中发现了一个问题,网上大部分讲解数字签名的文章好像和真正的签名算法有所出入,最后在前组长以及查看《密码编码学与网络安全》数字签名这一章才让我有点清晰。web

网上的资料关于数字签名的流程主要为:服务器将内容进行hash获得内容的摘要,而后使用私钥加上摘要完成签名,而后将内容以及签名一块儿发给接收方,接收方收到以后使用服务器的公钥进行解密获得摘要一,而后再使用和服务器同样的hash算法对内容进行hash获得摘要二,而后对比两个摘要是否相等,若是相等就说明签名经过,不相等就验签失败。算法

实际运用并不顺利

带着认识开始作签名任务,发如今和后台对接的时候有点小差异,我理解的是要解密对比摘要,很后台说的验签有点出入(内容hash+公钥+签名代入签名验证算法)得出结果?最后查了一下资料发现数字签名的通常模型为:后端

根据这个模型来看,第一部分理解都是没有问题的,可是问题就是处在验签过程,图上是直接使用使用内容hash+签名代入签名验证算法得出结果,和后台理解的完美贴合。看到这里我就更加疑惑了,难道网上的资料都有问题?并且维基给出来的数字签名原理和我之前理解的同样,以下图:安全

2560px-Digital_Signature_diagram_zh-CN.svg

第一部分和上图的过程一摸同样,惟一的区别就是验签过程。出于找到缘由的目的继续在《密码编码学与网络安全》这本书中寻找缘由,最终找到了影子:服务器

RSA方法:hash函数的输入是要签名的消息,输出是定长的hash码(前H),用发送发的私钥(PRa)将该Hash码加密造成签名,而后发送消息及其签名。接收方收到消息后计算hash码(后H),而且使用发送方的公钥对签名解密,若是计算出的Hash码与解密出结果相同,则认为签名是有效的。由于只有发送方拥有私钥,因此只有发送方可以产生有效的私钥。 DSA方法:DSA采用hash函数,获得hash码,它以hash码和为这次签名产生的随机数(k)做为签名函数的输入,签名函数依赖于发送发的私钥(PRa)和一组参数,这一组参数为通讯伙伴共有,能够认为这组参数构成全局公钥(PUG)。接受方,对接收到的消息产生hash,这个hash码和签名一块儿做为验证函数的输入,验证函数依赖于全局公钥和发送方公钥(PUa)。若验证函数的输出等于r成分则签名有效。网络

最后个人理解是:数字签名的模型是上图13.1这样的,可是在实现方式上是能够调整,所以网上的大部分资料应该都是相对于某一种签名方式来讲的,而不是对签名过程进行分析。app

apk签名实践

这里我只说前端方向,在这个任务中我采用的就是通常模型的基本流程,先生成一套RSA公私钥,前端直接将公钥硬编码。后端读取apk(buffer读取)并将内容进行hash(先后端协商使用sha256),依赖发送方的私钥将hash码代入签名函数,获得签名;把apk和签名一块儿发给前端,前端首先下载apk,而后读取apk文件(前端读取能够文本形式、dataurl形式、ArrayBuffer形式),先后端读取形式不一样验签必定失败,因为后台使用的是buffer读取,所以前端也只能采用buffer读取。⚠️(crypto-js中sha256不支持原生的ArrayBuffer,最后选择js-sha256,签名验证库:jsencrypt,除了文档不太友好以外都挺不错,自带一个测试demo)。文件读取方式统不统一就决定了这次签名能不能成功。svg

以上都是我的理解,若有错误,还得麻烦各位大佬指出来。

相关文章
相关标签/搜索