1.为何会有Https
由于Http有以下局限性
- 通信使用明文;
例如使用抓包工具,无需任何配置就可查看任何使用HTTP协议的通信数据 - 不验证通信方身份;
任何人都能向你发送请求,不管对方是谁都返回相应。 - 无法验证报文的完整性
遭到篡改,即没有办法确认发出的请求/相应前后一致。
Http的缺点解决方案
- 通信使用明文;
对通信数据进行加密。即便数据被窃听,对方依然需要花费一定的投入来破解,这种高昂的成本间接提高安全级别。 - 不验证通信方身份;
和服务端使用相同的算法,根据网络请求参数生成一个token,请求/应答时根据token来确定双方的身份。 - 无法验证报文的完整性
使用MD5/SHA1等算法进行完整性验证,对方接收到数据后,根据同样的算法生成散列值,比对发送方生成的散列值,即可验证数据的完整性。
Https=Http+SSL(Secure Sokcet Layer,安全套接字层)
- SSL原理及运行过程:
SSL协议基本思路是采用公钥加密法(最有名的是RSA加密算法)。大概流程是,客户端向服务器索要公钥,然后用公钥加密信息,服务器收到密文,用自己的私钥解密。
为了防止公钥被篡改,把公钥放在数字证书中,证书可信则公钥可信。公钥加密计算量很大,为了提高效率,服务端和客户端都生成对话秘钥,用它加密信息,而对话秘钥是对称加密,速度非常快。
HTTPS通信过程:

① 证书验证阶段
客户端发起 HTTPS 请求
服务端返回SSL证书
客户端验证证书是否合法,如果不合法则提示告警
② 数据传输阶段
当证书验证合法后,在本地生成随机数
通过公钥加密随机数,并把加密后的随机数传输到服务端
服务端通过私钥对随机数进行解密
服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输
为什么数据传输是用对称加密?
首先,非对称加密的加解密效率是非常低的,而 http 的应用场景中通常端与端之间存在大量的交互,非对称加密的效率是无法接受的;另外,在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密,所以 HTTPS 中内容传输加密采取的是对称加密,而不是非对称加密。
用了 HTTPS 会被抓包吗?
HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。
但是,正如前文所说,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。因此,只要客户端是我们自己的终端,我们授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。
通常HTTPS抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互,然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。
HTTPS和HTTP的区别主要为以下四点:
一、https协议需要到ca申请证书,一般免费证书很少,需要交费。
二、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl(Secure Socket Layer)加密传输协议。
三、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
四、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
Okhttp发送https请求代码步骤:
在ca机构申请证书,有.pfx格式和.cer两种格式;
okhttpClient有sslSocketFactory()方法设置ssl,需要传入sslSocketFactory和trustManager。
public HTTPSUtils(Context context) {
mContext = context;
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
final InputStream inputStream;
try {
inputStream = mContext.getAssets().open("srca.cer"); // 得到证书的输入流
try {
trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
} catch (IOException e) {
e.printStackTrace();
}
}
然后用该OkHttpClient执行请求
参考:
https://www.jianshu.com/p/f75a2af623a7
https://buder.blog.csdn.net/article/details/125411084
网友评论