—— 加餐开始 ——
相关技术#
SSL/TLS#
为了解决 HTTP 明文传输信息的安全问题,HTTPS 在 HTTP 的基础上引入了 SSL/TLS (Secure Sockets Layer / Transport Layer Security) 安全协议,使得信息能够加密传输。
我们先来看一下 SSL/TLS 的发展历史:
其实,SSL 是 TLS 的前生。
SSL 是网景公司设计的,在 SSL 3.0 后,网景公司将 SSL 交给了 IETF(互联网工程任务组),IETF 将 SSL 标准化,推出 TLS 1.0(= SSL 3.1),并将其录入 RFC(记录互联网规范、协议、过程等的标准文件)。经过更新迭代,
目前(2022 年 5 月)使用的 TLS 版本只剩下 1.2 和 1.3。
PS:图里为什么没有看到 SSL 1.0 呢?因为它存在很大的安全漏洞,所以根本没有被公开发布。
参考:
-
SSL/TLS 历史与前沿导览——Blog
-
SSL/TLS 协议各版本间的差异—— 安信证书
关于 TLS 握手的过程,我们简单看下下面这张图(左边是单向认证过程,右边是双向认证过程):
可以看到:
-
TLS 握手是在建立了 TCP 连接之后;
-
双向认证过程中,客户端也会发送自己的证书给服务端;
-
在 ChangeCipherSpec 后,信息就是加密传输的了;
整个 TLS 握手过程主要涉及传递证书、密钥交换等步骤,具体的原理,我这里推荐一些不错的资料~
可以带着2 个问题去看下面的资料:1)ClientHello 只是简单的说 “Hello” 吗?2)加密传输信息所用的密钥是怎么来的?(在后面的「实践部分 > WireShark」会公布答案,大大推荐通过网络包分析工具 WireShark 加深对 TLS 握手过程的理解。)
-
视频:SSL/TLS 握手过程——bilibili
-
文章
-
SSL/TLS 协议运行机制的概述—— 阮一峰
-
HTTPS - 揭秘 TLS 1.2 协议完整握手过程——51CTO
-
HTTPS RSA 握手解析—— 小林 Coding
-
HTTPS ECDHE 握手解析—— 小林 Coding
-
Tips:从小林 Coding 的文章可以发现,上图里的流程不是绝对的,因为不同的密钥交换算法(RSA、ECDHE...),对应的流程会有差异,比如基于 RSA 的密钥交换算法的流程中,没有 ServerKeyExchange 消息。
SSH#
SSH(Secure Shell)也是一种网络安全协议,也是由 IETF 制定的。但它是基于 TLS 之上的应用层协议(TLS 作用于运输层与应用层之间),通过加密和认证机制实现安全的访问和文件传输等业务。如果你经常用云主机或者 Github,那你对它一定不陌生~
SSH 连接的建立过程可以分为 3 步:
1)客户端验证服务器
你在首次 SSH 连接云主机的时候,应该见过下面这张图:
客户端收到了云主机的一些信息,关键是这里的 “指纹”(即 ECDSA 签名算法中公钥的 SHA-256 值),我们可以通过ssh-keyscan -t ECDSA -p 22 [host] > key.pub
获取服务器的真实公钥,然后通过ssh-keygen -E sha256 -lf key.pub
计算其 SHA256 值,与图中的 “指纹” 比对。如果一致,再决定连接。
由此可见,这里的验证过程是由客户端控制的,客户端可以不做任何比对,直接信任连接,但这样存在风险。
2)生成信息加密传输的密钥(通过密钥交换算法),之后的通信均加密
3)服务器验证客户端(2 种方式)
a. 客户端没有上传公钥:服务端会给客户端一个公钥,客户端使用该公钥加密用户信息(如密码),传给服务端,服务端校验通过后,连接建立成功。
b. 客户端提前上传了公钥到服务端:服务端会利用该公钥加密一个随机数发给客户端,客户端使用对应的私钥解密,再传给服务端,服务端校验通过后,连接建立成功。
参考:SSH 免密登录原理与实现—— 掘金
iOS 签名#
从图可以看出,iOS 签名其实是一个很复杂的过程,一段文字可能无法详细描述。
这里只需要知道 iOS 签名中 2 个必不可少的重要文件即可:
1).mobileprovision 文件:又叫 PP 文件(图中为 Provisioning Profile),可以把它理解为证书的升级版,里面不仅有 1 个以上的 iOS 开发者证书,还有各种其它信息。
2).p12 文件:由开发者证书和对应私钥组成,与图中的关键步骤 2 和 4 相关。Xcode 打包时需要搜索 Keychain 里属于 PP 文件中证书集合的证书,取出里面的私钥对 App 进行签名。
详细的讲解可以看我之前的文章:iOS | 图解 iOS 签名背后的原理,这也是本文的源头。
记住,如果你遇到 iOS 签名打包相关的问题,就先从上面的 2 个文件里入手吧~
一些实践#
最后,介绍两个不错的实践工具,来巩固今天的内容。
OpenSSL#
OpenSSL 是一个开源的密码学工具包,我们可以尝试用下面的脚本,复习一下今天学习的算法。
# Generate private key (RSA)
openssl genrsa -out private.pem
# Generate public key from private key
openssl rsa -in private.pem -pubout -out pubkey.pem
echo "hello, world" > test.txt
# Encrypt
openssl rsautl -encrypt -pubin -inkey pubkey.pem -in test.txt -out test.enc
# Decrypt
openssl rsautl -decrypt -inkey private.pem -in test.enc -out test.dec
# Signature (hash:SHA-256)
## Generate
openssl dgst -sign private.pem -sha256 -out test.sig test.txt
## Verify
openssl dgst -verify pubkey.pem -sha256 -signature test.sig test.txt
# View Key as text
## Private key
openssl rsa -in private.pem -noout -text
## Public key
openssl rsa -pubin -in pubkey.pem -noout -text
# Generate a self-signed certificate
# {Creating a Self-Signed Certificate With OpenSSL——Baeldung}
...
参考:
-
openssl——Linux 命令大全
WireShark#
WireShark 是一个开源的网络包分析工具,用它来深入理解各种网络协议准没错~
下面,我们先回顾一下「相关技术 > SSL/TLS」那一节提出的问题:
1)ClientHello 只是简单的说 “Hello” 吗?
2)加密传输信息所用的密钥是怎么来的?
接下来,打开 WireShark,对获取的网络包简单做一下过滤,如ip.addr == 115.236.119.85 && tls
。
可以看到,ClientHello 里传递的信息还不少,关键信息包括 TLS 版本、随机数(密钥交换算法用)、支持的 21 种加密套件(可供服务端选择的密钥交换算法)等。这也就解答了上面的第 1 个问题。
继续分析后面的每一条信息,我们还会发现在 ServerHello 里,服务端选择了一种密钥交换算法,最终通过该算法生成了加密传输信息所用的密钥。这也就解答了上面的第 2 个问题。
更多的细节,等着你安装 WireShark 去探索~
—— 加餐结束 ——