加密和签名

基本知识

  1. ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)。
    计算机中存储时要使用二进制数来表示,具体用哪些二进制数字表示哪个符号,这就叫编码。而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码。

  2. Base64:
    一种用64个字符来表示任意二进制数据的方法。使用3个字节为一组通过查找ASCII表找到对应二进制3*8=24bit,然后分成4组24/4=6bit,前面补0,转10进制数,作为索引查Base64表找到对应字符。Base64表索引0-63分别是A-Za-z+/。(为什么是3个自己分成4组?我猜是Base64表有64个字符,最大只能是2^6,也就是6bit,然而是6bit和一个字节8bit的最小公倍数的就是24bit,也就是3个字节)。

  3. 数字签名:
    也称之为数字摘要法(Digital Digest)或数字指纹法(Digital Finger Print)。hash签名是最主要的数字签名方法。采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。常用的hash算法有MD5和SHA1,MD5算法摘要的消息有128个比特位,SHA-1算法摘要的消息最终有160比特位的输出。

  4. 签名文件和证书:
    首先了解下数据交互的流程:

    1. 发送方明文消息数字摘要
    2. 发送方私钥加密数字摘要,生成签名文件
    3. 发送方把公钥给接收方,并发送明文消息和签名文件
    4. 接收方收到消息,用公钥解密签名文件,并用相同摘要算法摘要明文消息
    5. 判断解密后的摘要跟重新生成的摘要比较,若一样表示消息为损坏。

    上面的流程解释了签名文件即用私钥加密的明文消息的摘要的文件。只是第三步怎么把公钥给接收方,有怎么保证接收方的公钥不会被他人更换,为了解决这个问题所以就有了证书。

    证书中心(certificate authority,简称CA)是一个统一的证书管理机构。它管理所有需要发送数据方的公钥,对公钥进行认证和加密。认证加密后的公钥,即是证书,又称为CA证书,证书中包含了很多信息,最重要的是申请者的公钥。

    CA机构在给公钥加密时,用的是一个统一的密钥对,在加密公钥时,用的是其中的私钥。这样,申请者拿到证书后,在发送数据时,用自己的私钥生成签名,将签名、证书和发送内容一起发给对方,对方拿到了证书后,需要对证书解密以获取到证书中的公钥,解密需要用到CA机构的”统一密钥对“中的公钥,这个公钥也就是我们常说的CA根证书,通常需要我们到证书颁发机构去下载并安装到相应的收取数据的客户端,如浏览器上面。这个公钥只需要安装一次。有了这个公钥之后,就可以解密证书,拿到发送方的公钥,然后解密发送方发过来的签名,获取摘要,重新计算摘要,作对比,以验证数据内容的完整性。

Apk签名

Android系统在安装APK的时候,首先会检验APK的签名,如果发现签名文件不存在或者校验签名失败,则会拒绝安装,所以应用程序在发布之前一定要进行签名。

给APK签名可以带来以下好处:

  • 应用程序升级
    如果想无缝升级一个应用,Android系统要求应用程序的新版本与老版本具有相同的签名与包名。若包名相同而签名不同,系统会拒绝安装新版应用。

  • 应用程序模块化
    Android系统可以允许同一个证书签名的多个应用程序在一个进程里运行,系统实际把他们作为一个单个的应用程序。此时就可以把我们的应用程序以模块的方式进行部署,而用户可以独立的升级其中的一个模块。

  • 代码或数据共享
    Android提供了基于签名的权限机制,一个应用程序可以为另一个以相同证书签名的应用程序公开自己的功能与数据,同时其它具有不同签名的应用程序不可访问相应的功能与数据。

  • 应用程序的可认定性
    签名信息中包含有开发者信息,在一定程度上可以防止应用被伪造。例如网易云加密对Android APK加壳保护中使用的“校验签名(防二次打包)”功能就是利用了这一点。


签名的目的:

  • 要确定消息的来源确实是其申明的那个人
  • 要保证信息在传递的过程中不被第三方篡改,即使被篡改了,也可以发觉出来。

签名原理:

  • 对Apk中的每个文件做一次算法(数据摘要+Base64编码),保存到MANIFEST.MF文件中
  • 对MANIFEST.MF整个文件做一次算法(数据摘要+Base64编码),存放到CERT.SF文件的头属性中,在对MANIFEST.MF文件中每一条记录做一次算法(数据摘要+Base64编码),存放到CERT.SF文件中。
  • 对CERT.SF文件做签名,内容存档到CERT.RSA中,RSA文件还包含了签名的公钥、签名所有者等信息。

对一个APK文件签名之后,APK文件根目录下会增加META-INF目录,该目录下增加三个文件:
MANIFEST.MF
NETEASE.RSA
NETEASE.SF
.RSA文件还可能是.DSA文件,RSA与SF文件的文件名可以更改,但是它们的命名必须一样。


为什么要这么设计签名流程呢?

  • 如果你改变了apk包中的任何文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是验证失败,程序就不能成功安装。
  • 如果你改变了apk包中的任何文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是验证失败,程序就不能成功安装。
  • 如果你还不死心,继续计算MANIFEST.MF的摘要值,相应的更改CERT.SF里面的值,那么数字签名值必定与CERT.RSA文件中记录的不一样,还是失败。
  • 那么能不能继续伪造数字签名呢?不可能,因为没有数字证书对应的私钥。

所以,如果要重新打包后的应用程序能再Android设备上安装,必须对其进行重签名。只要修改了Apk中的任何内容,就必须重新签名,不然会提示安装失败。

Https加密通讯过程

HTTPS在传输过程中是可以通过加密来保护数据安全的,以免用户敏感信息被第三方获取。 可以说HTTPS是HTTP的升级版、安全版。


交互过程.png
  1. 浏览器请求服务器地址
  2. 服务器返回公钥
  3. 浏览器验证公钥是否有效,无效弹框警告,有效生成随机秘钥,然后用服务器公钥加密生成的随机秘钥发送给服务端
  4. 服务端收到后用私钥解密出随机秘钥
  5. 之后服务端和浏览器传输数据就用随机必要加密传输

其中浏览器验证服务端证书是TLS协议的工作,它是基于TCP协议。在建立连接的时候先进行TCP连接握手,然后进行TLS握手,过程如下

  1. 浏览器高速服务端支持的加密算法列表
  2. 服务端获取浏览器的加密算法列表,选择一个,加上证书公钥给到浏览器
  3. 浏览器用服务端选择的加密算法用服务端给的公钥加密一个随机生成的对称秘钥给到服务端
  4. 服务端收到后用私钥解密得到对称秘钥,发送用秘钥解密的信息给浏览器,握手结束。

证书的校验是浏览器会预置一些公认的根证书,拿到服务端的证书,然后后倒退到根证书浏览器中是否有,如果有则代表证书可信。如果证书是自己生成的,那需要在浏览器安装

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容