安卓应用通信安全(一)

本文主要介绍安卓应用通信安全的一些背景知识,如 SSL/TLS 介绍,证书等。

大部分的安卓应用都免不了与后端服务器进行通信。在通信过程中,主要面临两方面的风险:1、中间人攻击。当通信使用 HTTP 等明文协议,通信内容可被嗅探甚至篡改。2、通信内容被攻击者分析。使用加密的协议,虽然避免了中间人攻击,但是攻击者仍然可以通过各种方式获取请求内容,然后针对性的进行漏洞挖掘。本章的内容将围绕着这两方面展开。

一、背景知识

1、SSL/TLS 简介

为了应对中间人攻击,通常会采用安全套接字层 (SSL,现在技术上称为传输层安全协议 (TLS))来对通信进行加密传输。

如上图所示,当 SSL 与 HTTP 协议相结合就形成了 HTTPS,当 SSL 与 POP3 相结合就形成了 POP3S。

SSL/TLS 的握手过程如下图(了解下就好):

1)、Client hello

客户端向服务端发送 Client Hello 消息,包含支持的SSL的最高版本(TLS 1.0 表示为 SSL 3.1)以及它支持的密码套件列表。 密码套件信息包括加密算法和密钥长度。

2)、Server hello

服务端会通过客户端发过来的信息,选择一份双方都支持的最高 SSL/TLS 版本,确定一个双方都支持的最佳密码套件,并向客户端发送 Server Hello 消息。

3)、Certificate(可选)

服务端向客户端下发证书或者证书链(通常是 X.509 证书)。证书中会包含服务端的公钥、签发机机构、域名等信息,以供客户端校验。

4)、Certificate request(可选)

如果服务端需要校验客户端身份的话,会发送此信息要求客户端上报证书以供服务端校验。通常在安全性要求较高时候使用。

5)、Server key exchange(可选)

如果来自证书的公钥信息不足以进行密钥交换,则服务器向客户端发送服务器密钥交换消息。 例如,在基于 Diffie-Hellman(DH)的密码套件中,此消息包含服务器的 DH 公钥。

6)、Server hello done

服务器告诉客户端它已完成初始协商消息。

7)、Certificate(可选)

如果服务端发送了第4步消息,客户端会在这里向服务端发送自己的证书或者证书链。

8)、Client key exchange

客户端生成用于创建对称加密密钥的信息。 对于 RSA,客户端使用服务器的公钥加密此密钥信息并将其发送到服务器。 对于基于 DH 的密码套件,此消息包含客户端的 DH 公钥。

9)、Certificate verify(可选)

如果客户端执行了第7步,那么会发送此消息。 其目的是允许服务器完成对客户端进行身份验证的过程。 在此消息中,客户端会发送使用哈希算法签名的信息。 当服务器使用客户端的公钥解密此信息时,服务器能够对客户端进行身份验证。

10)、Change cipher spec

客户端发送一条消息,告知服务器更改为加密模式。

11)、Finished

客户端告诉服务器它已准备好开始安全数据通信。

12)、Change cipher spec

服务器发送一条消息,告知客户端更改为加密模式。

13)、Finished

服务器告诉客户端它已准备好开始安全数据通信。 这是 SSL 握手的结束。

14)、Encrypted data

客户端和服务器使用对称加密算法进行通信。

15)、Close Messages

在连接结束时,每一方发送close_notify消息以通知对等方连接已关闭。

总结一下,SSL/TLS 保证通信安全主要是通过对称加密算法(AES等)对通信内容进行加密传输,从而保证通信内容的安全。而对称算法的加密密钥是通过非对称加密算法(RSA等)来进行交换的,其主要依赖于服务端的公钥,此公钥存在于服务端的证书中。

2、数字证书

证书通常是指 X.509 格式证书,是由Netscape 当初设计 SSL 协议的时候定义的。其是服务端公钥的载体,同时还包含很多其他信息,如签发者信息、以及证书申请者相关的信息(国家、组织名称、常用名称等等)、加密算法、签名算法、签名指纹等。下图展示了 baidu.com 的证书部分信息。

在证书校验时候,签发者(CA)信息很重要。那么,为什么一个证书还需要有签发者呢?我们知道任何组织或个人都可以生成自己的数字证书,并设置证书中的任何信息。当客户端与服务端通信的时候,客户端就很难确认当前证书是否真的是服务端组织的真实证书。这个时候,一个比较可行的方案就是有个客户端信任的第三方,这个第三方为服务端证书进行签名,来证明证书的真实性。以 Android 系统为例,其预置了知名的权威签名机构公钥证书,可以判断服务端证书是否为这些机构签发。如果不是知名的权威机构签发,则认为证书是非法的,不会建立 SSL/TLS 通信。

除了签发者(CA)信息之外,证书中的常用名称(Common Name)也是比较重要的信息,常被用来校验HTTPS通信的域名是否正确。

3、自签名证书

下面使用 openssl 工具,模拟一下自己作为 CA 对证书进行签名的过程。

1)、生成CA的根证书,依次执行以下命令

生成CA私钥文件ca_private.key:

openssl genrsa -out ca_private.key 2048

生成X.509证书签名请求文件ca.csr:

openssl req -new -key ca_private.key -out ca.csr

在这一步会要求输入一些信息,如下:

生成X.509格式的CA根证书ca_public.crt(公钥证书,一般会预置到系统中):

openssl x509 -req -in ca.csr -signkey ca_private.key -out ca_public.crt

2)、生成服务端证书

生成服务器私钥文件server_private.key:

openssl genrsa -out server_private.key 2048

根据服务器私钥生成服务器公钥文件server_public.pem:

openssl rsa -in server_private.key -pubout -out server_public.pem

服务器端需要向CA机构申请签名证书,在申请签名证书之前创建自己的证书签名请求文件server.csr:

openssl req -new -key server_private.key -out server.csr

填写的信息如下:

3)、使用自有 CA 对服务端证书签名

签名过程需要 CA 的公钥证书和私钥参与,最终颁发一个带有 CA 签名的服务器端证书 server.crt:

openssl x509 -req -CA ca_public.crt -CAkey ca_private.key -CAcreateserial -in server.csr -out server.crt

查看生成的证书信息:第一个框中是 CA 的信息,第二个框中就是证书所有者的信息。

参考:https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html

https://jaq.alibaba.com/community/art/show?articleid=545

http://www.zytrax.com/tech/survival/ssl.html

https://github.com/houugen/Android_NetFrameword

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180826G150D100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券