非对称加密
非对称加密可以对任何二进制的数据进行加密。
原理:使用公钥对数据加密得到密文,使用私钥对数据解密得到原数据,它加密和解密使用同一个加密算法。
延伸用途:数字签名。
经典算法:RSA、DSA
对数据进行非对称加密可以保证没有私钥的人看不到原文,但是不能防止 中间人伪造消息。因为消息是使用公钥加密的,而中间人可以获得双方的公钥,对消息使用公钥加密从而伪造消息。
解决这个问题的办法是使用私钥对数据进行签名。
签名与验证

没有私钥的人无法无法伪造出签名后摘要
TCP/IP 协议族
由一系列协议所组成的一个网络协议族
网络为什么要分层?
由于网络不稳定,所以一定需要重传的机制,其中包括数据分块,数据重传等,这些功能是通用的,需要分层将这些功能复用。tcp有重传机制,udp没有重传机制。
应用层(http,ftp,dns)
传输层(tcp,udp)负责数据分块和重组,以及是否重传
网络层 只负责数据的传输,对tcp和udp提供传输的支持
数据链路层 以太网、wifi。提供物理支持
对于一个url:http://22.22.22.22:80/users
22.22.22.22 是属于网络层的东西,80端口是属于传输层的东西

TCP连接
- 什么叫做连接?
http是无状态的,tcp连接是有状态的。相互认识的过程就是建立连接的过程。连接是靠端口认识的,成功建立一个tcp连接后会获得一个socket - 三次握手与四次挥手
总体来说就是呼叫、应答、回应
建立连接为什么需要三次握手?
- 第一是为了保证两台服务器都完全没有问题,各自具备发报和收报能力
- 第二是防止出现请求超时导致脏连接。如果只进行两次握手,那么任意一次建立连接的请求都会使服务端建立连接。如果有一条超时的建立连接的请求传输到服务端,但客户端此时已关闭,服务端依然会建立连接,这个连接就是无效的脏连接。
关闭连接为什么需要四次挥手?
为什么需要关闭连接?因为要省资源,端口资源,内存资源等。
因为要尽可能确保连接正确关闭
- 长连接的实现方式:心跳
HTTPS
全称是HTTP over SSL或HTTP over TLS,TLS是SSL的升级版本,本质是一个东西。
定义:在HTTP之下增加的一个安全层,用于保障HTTP的加密传输。
本质:在客户端和服务器之间用非对称加密协商出一套对称密钥,每次发送信息之前将内容加密,收到之后解密。
HTTPS 连接
- 客户端发送 client hello,包含:
可选的TLS版本集合
可选的Cipher Suite加密套件(非对称加密算法、对称加密算法、哈希算法)
客户端随机数 - 服务端发送 server hello,包含:
选择的TLS版本
Cipher Suite加密套件
服务器随机数 - 服务器发送证书至客户端
- 客户端验证证书是合法的
- 客户端使用服务器公钥加密一个随机数 pre-master secret,将其发至服务端,服务端收到后解密
- 客户端和服务端各自使用 服务器随机数、客户端随机数、pre-master secret 计算出一个 master secret,两端的值是一样的
- 两端再使用 master secret 计算出客户端加密秘钥、服务端加密秘钥、客户端 MAC secret、服务端 MAC secret。至此,对称加密的秘钥就协商好了。
- 客户端和服务器相互确认,发送Finished
服务器证书的验证
证书内容包括
1.服务器公钥(原数据)
2.对服务器证书的签名(使用证书签发机构的私钥加密的)
3.证书签发机构的公钥(验证签名的公钥)
4.证书签发机构证书的签名
5.根证书机构的公钥(操作系统安装时已经存在于操作系统)
验证证书就是验证服务器公钥合法性以及服务器主机名的合法性

验证签名证书的使用场景:
禁止app使用charles抓包
参照 https://blog.csdn.net/u010788143/article/details/77374575
/** 不做任何证书校验 */
fun getSslSocketFactory(): SSLSocketFactory {
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, arrayOf(getTrustManager()), SecureRandom())
return sslContext.socketFactory
}
fun getTrustManager(): X509TrustManager {
return object : X509TrustManager {
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
}
}
/** 本地证书校验,创建okhttp客户端时,将信任的证书添加进来 */
fun getSslSocketFactory2(): SSLSocketFactory {
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, arrayOf(getTrustManager2()), SecureRandom())
return sslContext.socketFactory
}
fun getTrustManager2(): X509TrustManager {
val certificateFactory = CertificateFactory.getInstance("X.509")
val keystore = KeyStore.getInstance(KeyStore.getDefaultType())
keystore.load(null)
val cerInput1 =
BaseSdkApplication.applicationContext.resources.openRawResource(R.raw.fooww_com)
keystore.setCertificateEntry("fooww", certificateFactory.generateCertificate(cerInput1))
if (BuildConfig.FLAVOR == "canary") {
val cerInput2 =
BaseSdkApplication.applicationContext.resources.openRawResource(R.raw.charles_ssl_proxying_certificate)
keystore.setCertificateEntry("charles", certificateFactory.generateCertificate(cerInput2))
}
val trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(keystore)
return trustManagerFactory.trustManagers[0] as X509TrustManager
}
网友评论