一、k8s集群手动生成用户证书
TypeScript
#使用win10操作系统下的gitbash执行命令
#生成客户端私钥
openssl genrsa -out day21-adam.key 2048
#使用私钥生成带有私钥签名的CSR
openssl req -new -key day21-adam.key -out day21-adam.csr -subj '/CN=adam'
#k8s集群管理员创建csr对象
csr.yaml
#将user发来的day21-adam.csr进行base64编码,再放到CSR对象里。
#base64作用:将任意二进制数据(比如图片、文件、加密后的数据)转换成一个只包含可打印 ASCII 字符的字符串!!它只是格式转换!
cat day21-adam.csr | base64 | tr -d "\n"
#将加密结果填入request,然后apply,再describe查看CSR对象
kubectl describe csr adam
#发现status是pending。需要管理员approve
#approve这个命令背后,执行了用CA(也就是k8s服务器集群)的私钥给这个 CSR对象 签名的操作。签了名它就不再只是CSR,它有证书了:
kubectl certificate approve adam
#approve之后,user adam怎样拿到证书?
kubectl get csr/adam -o yaml > day21-adam-certificate.yaml
#将certificate字段解码 base64 -d
echo <粘贴certificate字段> | base64 -d
#就会得到证书:
-----BEGIN CERTIFICATE-----
MIIC9DC省略一堆乱码V5BVZ74q3g==
-----END CERTIFICATE-----
#下一步:把这个证书放到kube config, assign roles
于是,adam客户端现在有:1 k8s服务器的CA证书,证明k8sAPI身份,2 自己的经过CA签名的证书,证明自己的身份,内含自己的公钥, 3 自己的私钥。服务器端也一样,有自己的私钥、自己的证书、对方的证书。此后,每次adam发起请求连接服务器,都会执行一个完整的 TLS 握手过程,最终目标就是协商出一个会话密钥。双方的永久私钥不参与计算,只做身份验证。
步骤如下:
第一步:双方互查对方的证书,并用自己的私钥签名一个"密钥交换参数"。
第二步,双方交换一个随机数,并且双方会使用一种算法(例如 Diffie-Hellman 或其变种 ECDHE)临时生成一对公钥和私钥。这些临时密钥只用于本次会话。
第三步:交换各自的临时公钥,结合各自的私钥计算出"预主密钥",再结合之前的2个随机数,最终得出相同的(对称密钥)会话密钥(Master Key/Session Key),也就是协商完成了。接下来所有数据都会使用这个对称密钥进行加密和解密。
二、从零开始理解TLS协议
二点一、网络协议的层级
| 序号 | 层级名称 (中文) | 层级名称 (英文) | 包含的主要协议 | 作用 |
|---|---|---|---|---|
| 4 | 应用层 | Application Layer | HTTP, FTP, SMTP, DNS, SSH... | 处理应用程序之间特定的数据格式和协议。 |
| --- | ⚠️ TLS/SSL 位于此 | --- | TLS/SSL | 为应用层提供加密和身份认证服务。 |
| 3 | 传输层 | Transport Layer | TCP, UDP | 提供进程间的可靠(TCP)或不可靠(UDP)数据传输。 |
| 2 | 网络层 | Internet Layer | IP | 负责数据包的寻址和路由,让数据找到目标机器。 |
| 1 | 网络接口层 | Network Access | Ethernet, Wi-Fi | 负责数据的物理传输(网线、光纤、无线信号)。 |
二点二、SSL/TLS 是什么?
TLS (Transport Layer Security)是SSL (Secure Sockets Layer)的升级版,现在访问网站时使用的都是 TLS 协议,但是你还是会听人说SSL证书,SSL是历史遗留名称,因此二者经常混淆着讲。是客户端和服务器之间,为了安全传输而使用的协议,它提供三个基本安全保证:
-
加密 (Encryption): 确保第三方无法读取传输的数据。即使数据被截获,看到的也只是乱码。
-
认证 (Authentication): 确保你连接到的是你想要的服务器,而不是一个冒充者。
-
完整性 (Integrity): 确保数据在传输过程中没有被篡改。
为什么要从以上三个角度保障安全?
因为网络就是由非常多中转站(路由器/交换机)组成的一个大网,任何数据传输过程都要经由非常多的中转站,最终传到接收方。任何人都能在网络上拦截/复制/查看传输中的数据包,这无法避免。因此,想让数据安全,就需要保证数据:1 即使被中途截获也看不懂,2接收方不是冒充者,3数据没有被篡改,从这三个角度保证安全。
非对称加密的工作原理,能看懂版
非对称加密目的是:保证只有私钥持有者才能查看数据,从而实现保密通信(confidentiality)。
你(无论是客户端还是服务端)有一对钥匙:一个公钥一个私钥。你的私钥只有自己有,你的公钥你可以告诉任何人。这对钥匙的特征是:
-
使用公钥加密的数据,只能用私钥解密。
-
使用私钥进行签名(Signing) (签名是用某种算法加密的意思)的数据,使用公钥可以验签(Verification),也就是验证数据来源是正确的私钥持有者而且数据没有修改。
非对称加密:使用不同钥匙分别做加密和解密;
对称加密:使用同一把钥匙做加密和解密。
非对称加密数学原理:使用某算法(比如RSA)随机挑选了2个大质数并进行数学组合,然后系统同时输出2个不同、但数学上完美配对的字符串:
-
一个被标记为**"私钥"**(Master Key):这是完整的、包含所有秘密数学参数的钥匙。
-
一个被标记为**"公钥"**(Guest Key):这是从私钥派生出来的一个简化版本,它只包含进行加密和验证所需的信息,因此足以让任何人执行"上锁"(加密)和"验签"(验证签名)的操作,但不足以推导出私钥本身或进行"解锁"(解密)。
在kubernetes集群中用户生成自己的私钥使用了openssl genrsa 命令 ,它一次性生成了完整的密钥对(day21-adam.key),既是私钥,也包含了生成公钥所需的一切信息。
更详细好理解的TLS加密过程,可以看这组视频:
https://www.youtube.com/watch?v=_zyKvPvh808&list=PLIFyRwBY_4bTwRX__Zn4-letrtpSj1mzY&index=10
TLS"握手"是啥意思?
就是使用非对称加密 (公钥/私钥体系)的机制,安全地协商并交换一个临时的对称加密密钥的过程。
就像你和商家打招呼确认身份,最终两人都安全地拿到一只一样的秘密钥匙,以后传输信息都用这个钥匙解密,别人都没有钥匙所以看不到内容是啥。那么,怎样才能安全地拿到一样的钥匙?
TLS握手四个核心步骤
| 阶段 | 交互主体 | 关键动作/信息 | 核心目的 |
|---|---|---|---|
| 1. Hello (打招呼) | 客户端 \leftrightarrow 服务器 | 客户端发送支持的版本、密码套件和随机数 A。服务器回复选定的版本、选定的套件和随机数 B。 | 确定通信参数,生成握手所需的随机性。 |
| 2. Certificate (身份验证) | 服务器 \rightarrow 客户端 | 服务器发送其数字证书(包含公钥)和数字签名。 | **建立信任链:**客户端验证证书,确认服务器是真实的,而非冒充者。 |
| 3. Key Exchange (密钥交换) | 客户端 \leftrightarrow 服务器 | 双方使用非对称加密(如 RSA 或 ECDHE 算法)安全地协商出一个临时的对称密钥(会话密钥)。 | 机密性基础: 保证后续数据传输的加密性。 |
| 4. Finished (完成) | 客户端 \leftrightarrow 服务器 | 双方发送一个特殊的加密消息,确认它们成功计算出了相同的对称密钥。 | 确认通道: 双方切换到新加密通道,并验证加密功能正常。 |
数字证书:服务器向CA(一个第三方认证机构)提交自己的CSR(证书请求)
TLS1.3身份验证详细步骤
在 TLS 1.3 中,身份验证主要依赖于服务器证书 及其包含的数字签名 ,发生在握手的第二阶段(在双方发送 Server Hello 之后)。
阶段 I:服务器出示证书
在服务器发送完 Server Hello 消息(其中包含用于密钥交换的临时公钥 P_S)之后,它会立即发送其身份证明:
-
Certificate 消息: 服务器发送包含其身份信息的 数字证书链。
- 证书中包含了服务器的 域名 (例如
example.com)和 公钥(通常是 RSA 或 ECDSA 公钥)。
- 证书中包含了服务器的 域名 (例如
-
Certificate Verify 消息(签名): 这是身份验证的核心步骤。
-
服务器动作: 服务器使用自己的 证书私钥 ,对迄今为止传输的所有握手消息(从
Client Hello到它自己的Server Hello)的哈希值进行数字签名。 -
发送签名: 服务器将这个数字签名放在
Certificate Verify消息中发送给客户端。
-
阶段 II:客户端验证身份(核心)
客户端收到服务器的证书和签名后,立即开始验证工作。
步骤 1:验证证书的合法性(信任链)
客户端(浏览器)会进行一系列检查,以确保证书是可信的:
-
验证签名者: 客户端检查证书是否由其信任的根证书颁发机构 (CA) 签发。如果证书是中间 CA 签发的,客户端会沿着证书链向上验证,直到找到它信任的根 CA。
-
检查有效期: 检查证书是否在有效期内(未过期)。
-
检查域名匹配: 检查证书中的域名(Common Name 或 Subject Alternative Name)是否与用户正在访问的域名匹配。如果访问
example.com,但证书是malicious.com的,验证失败。 -
检查吊销状态: 检查证书是否已被吊销(虽然实际实施中可能复杂)。
如果这一步验证失败,客户端会立即终止连接,并向用户报告"连接不安全"。
步骤 2:验证服务器是否拥有私钥(防冒充)
这是最关键的步骤,用于防止冒充者使用偷来的证书。
-
客户端动作: 客户端取出服务器证书中的 公钥。
-
验证签名: 客户端使用这个公钥,对
Certificate Verify消息中的数字签名进行解密。 -
哈希对比: 客户端独立地计算所有握手消息的哈希值。
-
判断: 客户端对比:
\text{解密签名}(\text{服务器公钥}) \stackrel{?}{=} \text{哈希}(\text{所有握手消息})
-
如果匹配: 证明服务器确实拥有与证书中公钥配对的私钥。只有真正的服务器才能生成那个正确的签名。
-
如果不匹配: 身份验证失败,因为签名无效,说明服务器是冒充者或证书被篡改。
-
总结:TLS 身份验证是"双重验证"
| 验证点 | 目的 | 使用的加密技术 |
|---|---|---|
| 验证证书本身 | 确认证书是权威且合法的(信任链、域名、有效期)。 | CA 签名(客户端验证 CA 的签名)。 |
| 验证签名消息 | 确认服务器拥有私钥(确保证书没有被盗用)。 | 服务器私钥签名(客户端用服务器公钥验证)。 |
TLS1.3密钥交换详细步骤
步骤 1:客户端主动出击 (Client Hello)
客户端在第一次打招呼时,就做好了密钥交换的准备。
-
生成临时参数: 客户端选择一个双方都支持的 DH 组 (例如
X25519或P-256),并为该 DH 组生成一个临时的私钥 (D_C) 和一个对应的临时公钥 (P_C)。 -
发送公钥: 客户端将这个临时公钥 (P_C) 放在
Client Hello消息中的key_share扩展字段中,发送给服务器。
📝 状态: 客户端已经完成了其密钥生成工作,并预测服务器会接受它提供的参数。
步骤 2:服务器选择并响应 (Server Hello & Certificate)
服务器收到客户端的 Client Hello 后,立即做出反应。
-
选择参数: 服务器接受客户端提供的 DH 组(例如 X25519)。
-
生成临时参数: 服务器也为该 DH 组生成一个临时的私钥 (D_S) 和对应的临时公钥 (P_S)。
-
计算共享密钥: 服务器立即使用自己生成的临时私钥 (D_S) 和客户端发来的临时公钥 (P_C) ,计算出共享秘密值 (Z)。
Z = \text{ECDHE}(D_S, P_C)
-
发送公钥和身份: 服务器发送
Server Hello,并将自己生成的临时公钥 (P_S) 也放在key_share扩展中,然后发送自己的证书(用于身份验证)。
步骤 3:客户端计算共享密钥
客户端收到服务器的 Server Hello 后,立即计算共享秘密值。
-
接收公钥: 客户端接收到服务器的临时公钥 (P_S)。
-
计算共享密钥: 客户端使用自己生成的临时私钥 (D_C) 和服务器发来的临时公钥 (P_S) ,计算出共享秘密值 (Z)。
Z = \text{ECDHE}(D_C, P_S)
由于 ECDHE 的数学特性,客户端和服务器计算出的 Z 值是相同的。
步骤 4:生成最终会话密钥
现在,客户端和服务器都拥有了相同的 共享秘密值 (Z)。
- 密钥派生: 双方使用一个 密钥派生函数 (HKDF) ,将共享秘密值 (Z) 与双方的随机数(来自 Hello 消息)混合,计算出一系列用于加密、解密和数据完整性保护的最终会话密钥 (例如,
application_traffic_key)。
这完整过程中即便黑客截获了全部传输中的数据,也几乎不能推算出任何一方的私钥或共享密钥。于是达到了安全地在两端各自生成一样的密钥的结果。
二点三、HTTPS传输过程(TLS1.2版)
用户(浏览器)访问服务器,并互相进行数据传输的完整过程是怎样的?
第一步:TCP握手(图中1)
第二步:TLS1.2握手包含两次往返,验证身份、得到对称加密密钥(图中2和3)
第三步:使用对称密钥进行数据传输
参考:https://www.youtube.com/watch?v=j9QmMEWmcfo&t=66s

浏览器内置了CA(certification Authority)帮你确认你要访问的服务器证书有效,点开网址左侧的符号,右键就能看到证书细节:

题外话:SSH 和 SSL/TLS 协议的执行顺序分别是?为什么顺序不同?
SSH 的目标是建立一个可交互的、安全的远程会话 。它的首要任务是快速且私密地建立通信通道。
SSH协议执行哪些阶段:
| 阶段 | 动作 | 使用加密类型 | 侧重点 / 目标 |
|---|---|---|---|
| I. 建立通道 | 密钥交换(Diffie-Hellman/ECDH) | 非对称加密 | 机密性 :使用和TLS一样的非对称加密算法,最终协商出对称密钥。在第一步就确保后续的所有通信(包括登录凭证)都是加密的。 |
| II. 身份验证 | 服务器发起挑战 / 客户端签名 | 非对称加密 | 认证:服务器发一串数字给客户端,客户端用私钥签名,服务器用公钥验证签名从而确认了客户端身份。 |
| III. 数据传输 | 传输加密数据 | 对称加密 | 效率:使用协商出的对称密钥进行高效数据传输。 |
TLS/HTTPS 的目标是建立一个可信赖的、用于 Web 事务的连接 。它的首要任务是验证服务器的真实性 。可以说,SSH 的设计更偏向于通道安全 ,而 TLS 的设计更偏向于身份可信 。但最终,它们都成功地结合了非对称加密的安全性 和对称加密的高效率,实现了可靠的加密通信。