1 TLS安全密码套件解读
身份验证 算法强度模式
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
秘钥交换 密码 MAC或者PRF
秘钥交换算法(生成对称加密中所需要的秘钥)
身份验证算法(使用非对称加密算法来验证身份)
对称加密算法、强度、工作模式(AES_128_GCM
)
签名hash算法(sha256)
2 为什么对称加密算法包含强度和模式
2.1 XOR与填充
对称加密的核心就是XOR运算,由于XOR运算需要操作数和被操作数的长度一致,而现实中明文远远比秘钥要长,所以需要对明文进行分组然后才能执行XOR运算。
填充padding:
- Block cipher分组加密:将明文分成多个等长的Block模块,对每个模块分别加解密
- 目的:当最后一个明文Block模块长度不足时,需要填充
- 填充方法:
位填充: 以bit位为单位来填充
字节填充: 以字节为单位来填充
补零法: |DD DD DD DD DD DD DD DD| DD DD DD DD 00 00 00 00|
ANSI x9.23: |DD DD DD DD DD DD DD DD| DD DD DD DD 00 00 00 04|
ISO 10126: |DD DD DD DD DD DD DD DD| DD DD DD DD 81 A6 23 04|
RKCS7(RFC5652) |DD DD DD DD DD DD DD DD| DD DD DD DD 04 04 04 04|
AES算法就是使用RKCS7填充方法
2.2 使用工作模式来减少密文的特征
分组工作模式的定义: block cipher mode of operation:
允许使用同一个分组密码秘钥对多于一块的数据进行加密,并保证其安全性。
- ECB(Electronic codebook)模式
直接将明文分解为多个块,对每个块独立加密。
问题: 无法隐藏数据特征。
Plaintext Plaintext Plaintext
V V V
key ---->Block Cipher key ---->Block Cipher key ---->Block Cipher
Decryption Decryption Decryption
V V V
Ciphertext Ciphertext Ciphertext
key: 作为异或操作的一部分,做一些变换。
但是不管怎样做一些变换,都会导致一个问题,比如说我的明文是一张图片,那么明文的一些数据特征会在密文中得到显现。
- CBC(Cipher-block chaining)模式
每个明文块先与前一个密文块进行异或后,再进行加密
问题:加密过程串行化
Plaintext Plaintext Plaintext
Initialization | | |
Vector(IV)------>⊕ |---------------->⊕ |---------------->⊕
V | V | V
key ---->Block Cipher | key ---->Block Cipher | key ---->Block Cipher
Decryption | Decryption | Decryption
V--------| V--------| V
Ciphertext Ciphertext Ciphertext
- CTR(Counter)模式
通过递增一个加密计数器以产生连续的密钥流
问题:不能提供密文信息完整性校验
Nonce:随机数
Nonce+Counter Nonce+Counter Nonce+Counter
V V V
key ---->Block Cipher key ---->Block Cipher key ---->Block Cipher
Decryption Decryption Decryption
| | |
Plaintext---->⊕ Plaintext---->⊕ Plaintext---->⊕
V V V
Ciphertext Ciphertext Ciphertext
- GCM(Galois/Counter Mode: CTR+GMAC) 验证完整性: hash函数(不定长度的文本,通过同一个hash函数之后可以得到一个定长的较短的一个hash编码, 这个hash编码相当于它的一个指纹,通常一个好的hash函数会使得不同的输入,很难得到同一个hash值,也就是说碰撞的概率是很低的)
input hash sum
fox ----> Hash function --> DFCD3454
The red fox
runs across ---->Hash function --> 52ED879E
the ice
The red fox
walks across---->Hash function --> 46042841
the ice
有了hash函数之后呢,我们就有了这样的一个算法:MAC(Message Authentication Code),它可以实现对称加密的完整性。
sender: receiver:
Message(生成的密文) Message
| \ / |
| --> --> |
V \ / V
key-> mac算法 ->Message-- key->mac算法
(秘钥) | --->mac值-- |
| / \ |
| ----> --> mac->=?<=mac值
V / |
mac值 V
If the same MAC is found: then
the message is authentic and
Integrity checked
Else: something is not right
有了mac之后,就可以推出如下GCM算法:
{iv}
|
V
{Counter 0}-->{incr}-->{Counter 1}-->{incr}-->{Counter 2}
| | |
V V V
{E_k} {E_k} {E_k}
| | |
| V V
| {Plaintext 1}->(+) {Plaintext 2}->(+)
| | |
| V V
| {Ciphertext 1} {Ciphertext 2}
| | |
| V V
| +------------->(+) +--------->(+)
| | | | |
| | V | V
| {mult_H} {mult_H}------+ {mult_H}
| ^ |
| | V
| {Auth Data 1} {len(A)||len(C)}->(+)
| |
| V
| {mult_H}
| |
| V
+------------------------------------------->(+)
|
V
{Auth Tag}
3 如何在TLS握手中,由双方各自独立地生成后续对称加密时所要使用的秘钥
RSA密钥交换
事实上我们使用RSA算法所生成的公私钥,基于这些公私钥来生成对称加密所使用的秘钥,也是可行的。
# 由客户端生成对称加密的密钥
ClientDevice Server
| |
|-------------Hello-------------->|
| |
|<---------PublicKey--------------|
| |
| |
|--------(Secret)PublicKey--------|
| |
问题:没有前向保密性
什么叫做前向保密性呢?比如说现在有个中间人,我现在还没有破解server的私钥,我现在通过中间的一些网络设备把所有的报文都保存下来了,
然后,当某一天我破解了这个server的私钥,那么我就可以基于私钥破解出对称加密算法所使用的的秘钥了,最后就可以把所有的消息全部解了。
这就叫做没有前向保密性。
3.1 DH密钥交换
- 1976年由Bailey Whitfield Diffie和Martin Edward Hellman首次发表,故称为Diffie-Hellman key exchange,简称DH
- 它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建一个秘钥。
ClientDevice Server
| |
|-------------Hello-------------->| Private key 1
| |
PrivateKey2 |<---------PublicKey1-------------|
| |
| |
|----------PublicKey2------------>|
| |
PrivateKey2--------(Secret)-----------PrivateKey1
PublicKey1 PublicKey2
| |
TLS1.2:
浏览器 Web服务器(nginx)
1.Client Hello ^-------------------------------------->^
| 支持安全套件列表 |
| |
|<--------------------------------------| 2.Server Hello
| 选择安全套件 |
check |<--------------------------------------| 3.Server Certificates
certificate | 发送证书 |
validity | |
|<--------------------------------------| 4.ServerKey Exchange
| -ServerDH公钥 |
|<--------------------------------------| 5.Server Hello Done
| |
| |
6.ClientKey Exchange |-------------------------------------->|
| -ClientDH公钥 |
| |
7.生成密钥 | | 7.生成密钥
| |
| |
8.CipherSpec Exchange|-------------------------------------->|
Finished | |
(密钥交换结束) | |
|<--------------------------------------| 8.CipherSpec Exchange(密钥交换结束)
| | Finished
| |
| |
| |
| Encrypted data |
| |
我们的客户端首先发起一个Hello,我们server收到之后就知道了我们开始进行协商沟通了。
server先自己生成了一对公私钥,其中私钥它自己保存,叫做private key 1,然后把公钥public key1发送给
客户端。客户端接收到这个公钥之后呢,客户端自己也生成了一对密钥,私钥private key 2自己保存,
把公钥public key 2发送给server。
现在呢,客户端基于PrivateKey2和PublicKey1,用一种算法生成出来一个秘钥。
而server呢,基于PrivateKey1和PublicKey2,用一种算法也生成出一个密钥。
这两个密钥是相同的。
DH密钥交换协议举例:
* g(5),p(23),A,B公开
* a(6),b(15)保密
* 生成共同密钥K
Alice Bob
a,g,p b
A = g^a mod p, A=8 ----------g,p,A----------------> B = g^b mod p, B=19
K = B^a mod p, K=2 <---------B--------------------- K = A^b mod p, K=2
K = A^b mod p = (g^a mod p)^b mod p = g^(ab) mod p = (g^b mod p)^a mod p = B^a mod p
DH密钥交换协议的问题:
- 中间人伪造攻击
Alice 中间人 Bob
| | |
|----------------------->(1) |
| | |
| (2)<-----------------------|
| | |
1.向Alice假装自己是Bob,进行一次DH密钥交换,
2.向Bob假装自己是Alice,进行一次DH密钥交换
3.接着DH算法交换生成的密钥K,中间人就知道了
解决中间人伪造攻击: 身份验证(使用PKI),以检测第2步是否被攻击了。
- 计算过程中含有大量乘法,它的安全性依赖于大因素分解的困难性,所以需要比较长的秘钥位数
3.2 ECC椭圆曲线的特性
椭圆曲线的表达式: y^2 = x^3 + ax + b, 4a^3 + 27b^2 != 0
由于表达式左边是y的平方,所以它始终关于X轴对称,实际上它的图形并不是椭圆,只是某些运算和椭圆很像。
- +运算
- P+Q = R
- +运算的几何意义:R为P、Q连线与曲线交点在X轴上的镜像
- P + P = R
当P点和Q点重合的时候,就会出现P+P=R
- +运算满足交换律 a + b = b + a
- +运算满足结合律 (a+b) + c = a + (b + c)
接下来我们从代数的公式上看看如何计算P+Q=R的。
- 先计算出斜率m,再计算出R点的坐标 $ x_R = m^2 - x_P - y_P $ $ y_R = y_P + m(x_R - x_P) $ $ m=\begin{cases} \frac{y_P-y_Q}{x_P-x_Q} ,x_P \neq x_Q \ \frac{3x^2_P+a}{2y_P} ,P = Q\ \end{cases} $
ECC+运算举例:
* 设曲线: y^2 = x^3 - 7x + 10
* 设P=(1,2), Q=(3,4),计算出R(-3,-2)
* P在曲线上,因为2^2 = 4 = 1^3 - 7*1 + 10
* Q在曲线上,因为4^2 = 16 = 3^3 - 3*7 + 10 = 27 - 21 + 10
* R在曲线上,因为(-2)^2 = 4 = -3 - 7*(-3) + 10 = -27 + 21 + 10
$m = \frac{y_P-y_Q}{x_P-x_Q} = \frac{2-4}{1-3} = 1$
$x_R = m^2 - x_P - x_Q = 1^2 -1 -3 = -3 $
$y_R = y_P + m(x_R - x_P) = 2 + 1*(-3-1)=-2$
$y_R = y_P + m(x_R - x_P) = 4 + 1*(-3-3) = -2$
我们看到了ECC的几何意义和代数意义,它是如何实现TLS中的加密的呢。
ECC的关键原理:
Q=K.P
(K个P相加)- 已知K与P,正向运算快速
- 已知Q与P,计算K的逆向运算非常困难 已知Q点和P点,要计算出有多少个K是非常困难的。
所以在ECDH交换协议中,P点往往是已知的公共的一个点,而K呢就是已知的Client和Server他们各自的一个私钥,这个私钥乘以K之后,就得到Q这个公钥。然后把公钥交换给对方,就可以生成用于对称加密的一个秘钥。
3.3 DH协议升级:基于椭圆曲线的ECDH协议
ECDH秘钥交换协议:
- DH秘钥交换协议使用椭圆曲线后的变种,称为Elliptic Curve Diffie-Hellman key Exchange, 缩写为ECDH,优点是比DH计算速度快、同等安全条件下秘钥更短
- ECC (Elliptic Curve Cryptography):椭圆曲线密码学
- 魏尔斯特拉斯椭圆函数(Weierstrass ’s elliptic functions): y^2 = x^3 + ax + b。
ECDH的步骤:
- 步骤
- Alice选定大整数Ka作为私钥
- 基于选定曲线及曲线上的共享P点,Alice计算出
Qa=Ka.P
- Alice将Qa、选定曲线、共享P点传递给Bob
- Bob选定大整数Kb作为私钥,将计算了
Qb=Kb.P
,并将Qb传递给Alice - Alice生成秘钥Qb.Ka = (X,Y),其中X为对称加密的秘钥
- Bob生成秘钥Qa.Kb = (X,Y),其中X为对称加密的秘钥
- 为什么X值是一致的呢,因为椭圆曲线的加法满足交换律和结合律 Qb.Ka = Ka.(Kb.P) = Ka.Kb.P = Kb.(Ka.P) = Qa.Kb
3.4 TLS1.3
TLS1.3只支持以下5种安全套件:
TLS13-AES-256-GCM-SHA384
TLS13-CHACHA20-POLY1305-SHA256
TLS13-AES-128-GCM-SHA256
TLS13-AES-128-CCM-8-SHA256
TLS13-AES-128-CCM-SHA256
测试TLS站点支持情况:https://www.ssllabs.com/ssltest/index.html
握手过程中,TLS1.3有哪些改进:
因为在握手过程中,TLS1.2会有一个Client Hello和Server Hello来选择安全套件,
导致TLS1.2有了一个RTT这样的一个不必要的延时
那么TSL1.3中又是怎样解决的呢?
Client会在预先在握手之前就已经生成了它的Private Key2和Public Key2,
然后在握手的第一次中,就把Public Key发送给Server了。
而Server呢,同时也会生成自己的Private Key1和PublicKey1,
那接下来大家就可以共同的来通讯了。
在这样的一个过程中,有一个问题就是openssl 1.1.1中支持5种加密套件,
那么Client如何知道后续他们应该使用哪一种呢,通常Client会把这5种全部
生成各自的privateKey和PublicKey,然后把所有的PublicKey发送给Server,
由server选定某一种方式以后,并使用这一种曲线所使用到的这样的一个PublicKey,
并告诉我们的Client。
3.5 quic+tls1.3和tcp+tls1.3
4 附录: RSA算法
4.1 RSA算法中公私钥的产生
- 随机选择两个不相等的质数p和q
- 计算p和q的乘积n (明文小于n,也就是我们将明文转换为十进制之后,它必须小于n)
- 计算n的欧拉函数v = φ(n),即:
v = (p-1) * (q-1)
欧拉函数:所有小于n的正整数中,与n互质的数的数量 - 随机选择一个整数k 1 < k < v, 且k与v互质(它们的最大公约数是1)
- 计算k对于v的模反元素d:
(d*k)%v = (k*d)%v = 1
- 公钥: (k,n)
- 私钥: (d,n)
例如, p = 11; q = 29; n = 319 则:v = 280; k = 3; d = 187 public key: (3,319) private key: (187,319)
- 加密: c≡ m^k mod n m是明文, c是密文
- 解密: m ≡ c^d mod n
- 举例: 对明文数字123加解密 公钥(3,319)加密 123^3 mod 319 = 140 对140密文用私钥(187, 319)解密 140^187 mod 319 = 123 私钥(187,319)加密 123^187 mod 319 = 161 公钥 (3, 319)解密 161^3 mode 319 = 123
4.2 为什么说RSA算法是安全的呢?
比如说一个第三者拿到了这个公钥(3, 319),他能不能推导出(187,319)这个私钥呢。
由于n是已知的,所以只需要找到d,如何找到d呢,只要他拿到了v,它自然就找到了d。
v=(p-1)*(q-1)
,也就是说他必须找到p和q, 而p*q=n
,n是一个很大的数字。
对于一个很大的数n,要通过因式分解获取到p和q是非常困难的。
所以,RSA算法的安全性来源于对一个大数进行因式分解非常困难。
4.3 基于openssl实战验证RSA
|
|
注意,openssl genras -out private.pem
这一步生成的private.pem文件中,
包含了上节课中我们介绍的p,q,n,v,k,d等等信息。
- 从private.pem文件中提取出私钥: 私钥是使用ASN.1格式进行编码的,所以我们需要使用openssl的子命令asn1parse
|
|
- 从primary.pem文件中提取出公钥:
|
|
- 对hello.txt文件进行加解密
|
|
4.4 PKI(Public Key Infrastructrue)证书体系
-
基于私钥加密,只能使用公钥解密:起到身份认证的作用
-
由Certificate Authority (CA)数字证书机构将用户个人身份与公开密钥关联在一起。 比如说,我有一个网站,我的身份是什么呢,就是我的网站属于哪一家公司,属于哪一个国家,用作什么用途,等等。这些就是我的个人身份。 然后我的这个网站呢,我刚刚使用我的rsa算法生成了一个公钥,我把它公开出去了,我的公钥和我的个人信息交给CA机构以后呢, CA机构在核实完我的身份以后,就会颁发我一个数字证书(颁发数字证书的过程如下所示), 那么通过这样一种方式,就把个人身份和公开秘钥关联在一起了。
``` # openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt HashFunction Data ---------------> 101100110101(Hash值) (用户的个人身份) | |用ca机构自己的私钥(存放在ca.key中)进行加密 | V 存在server.csr中的用户公钥 111101101110(signature) ^________________________^ | 附加Data | V 公钥数字证书(server.crt) ```
-
浏览器认证的过程
公钥数字证书
/ \
/ \
Data 111101101110(signature)
| |
|HashFunction | 用CA机构的公钥(存放在ca.crt中)进行解密
V V
101100110101 ?= 101100110101
if the hashes are equal, the signature is valid.
上面用于解密的公钥,浏览器是如何获取的? 由于有多级CA机构,它们是一个链式结构,会使用递归的方式执行上面的解密流程, 直到到达Root CA,而Root CA的公钥是维护在操作系统的/etc/pki/tls/certs/ca-bundle.crt文件下的。 这就解决了,公钥在哪里的问题。
Owner's DN
Owner's public key Get certificate
Issuer's(CA)DN -------------------|
Issuer's(CA)signature V
^ Issuer's(CA)DN
|-----------------Owner's public key Get certificates
Verify signature Issuer's(Root CA)DN--------------------|
Issuer's(Root CA)signature V
^ RootCA's DN
|-------------------Root CA's public key
Verify signature Root CA's signature
- 证书申请和浏览器认证的过程
openssl genrsa -des3 -out server.key 2048
^ openssl req -new -key server.key -subj "/CN=tunnel-cloud" -out server.csr
| ^ openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
| | ^
| 证书签名申请(request |
| certificate issuance,CSR) | (CSR)
证书订阅人 --------------------> 登记机构 ------------------> CA(颁发证书)
| <----------------- (验证订阅人的身份)<-------------- |
| |
|部署证书 ------------------------------|
V v v
web服务器 CRL服务器 OCSP响应程序
^| ^ ^
|| | |
1.请|| 2.验 | |
求证|| 证签名 | |
书 || CERT | |
|V 3.检测吊销状态 | |
信赖方------------------------------------------------------------
如果使用Let’s Encrypt,你会发现这个证书只有三个月的有效期,如果使用其他大部分的ssl的CA颁发的证书, 一般是1年的有效期。那么这个有效期是怎样体现的呢?CA中心会把过期的证书放到CRL服务器里面,这个服务器 会把所有的过期证书形成一条链条,所以它的性能非常的差。所以推出了OCSP程序,OCSP可以就一个证书去查它 是否过期,所以浏览器是可以直接去查询OCSP响应程序的,但OCSP响应程序,性能还是不够高,所以Web服务器 (例如Nginx)会有一个OCSP开关,当打开开关以后,nginx会主动去查询OCSP响应程序,这样大量的客户端就可以 直接访问nginx就可以获取到这个证书是否有效。
4.5 用免费SSL证书实现一个HTTPS站点
https://github.com/go-acme/lego todo: 使用lego取代certbot
如果使用centos操作系统,就可以使用yum install python2-certbot-nginx
这样的一个工具就可以做到了。
当我们安装好这个工具以后,会提供一个命令叫做certbot,当我们为certbot命令指定–nginx参数之后,
它就会执行nginx配置的自动修改了
|
|
定时刷新证书:
|
|
刷新证书时遇到如下问题:
|
|
certbot帮助文档: https://certbot.eff.org/docs/using.html?highlight=domain#changing-a-certificate-s-domains
4.6 Q&A
- 检查私钥和证书是否匹配
如果两个命令输出的 MD5 值相同,则说明私钥和证书匹配;否则它们不匹配。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。