TLS 详解

TLS(Transport Layer Security)是一种安全协议,用于在HTTP上实现HTTPS,确保数据加密和身份验证。协议分为记录层和握手层,其中握手层通过非对称加密协商对称加密密钥,确保通信安全。记录层负责数据的分片、压缩、加密和MAC保护。握手过程包括ClientHello、ServerHello、证书交换、密钥计算、Finished消息等步骤,确保双方安全建立连接。常见的密钥交换算法有RSA和ECDHE,后者支持完美前向安全性。
摘要由CSDN通过智能技术生成

原文链接: blog.wangriyu.wang/2018/03-htt…

1. TLS 定义

SSL(Secure Sockets Layer) 安全套接层,是一种安全协议,经历了 SSL 1.0、2.0、3.0 版本后发展成了标准安全协议 - TLS(Transport Layer Security) 传输层安全性协议。TLS 有 1.0 (RFC 2246)、1.1(RFC 4346)、1.2(RFC 5246)、1.3(RFC 8446) 版本。

TLS 在实现上分为 记录层握手层 两层,其中握手层又含四个子协议: 握手协议 (handshake protocol)、更改加密规范协议 (change cipher spec protocol)、应用数据协议 (application data protocol) 和警告协议 (alert protocol)

2. HTTPS = HTTP over TLS.

只需配置浏览器和服务器相关设置开启 TLS,即可实现 HTTPS,TLS 高度解耦,可装可卸,与上层高级应用层协议相互协作又相互独立。

3. 加密

TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。

TLS 的基本工作方式是,客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥,然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取。

例如,在 HTTPS 协议中,客户端发出请求,服务端会将公钥发给客户端,客户端验证过后生成一个密钥再用公钥加密后发送给服务端(非对称加密),双方会在 TLS 握手过程中生成一个协商密钥(对称密钥),成功后建立加密连接。通信过程中客户端将请求数据用协商密钥加密后发送,服务端也用协商密钥解密,响应也用相同的协商密钥。后续的通信使用对称加密是因为对称加解密快,而握手过程中非对称加密可以保证加密的有效性,但是过程复杂,计算量相对来说也大。

4. 记录层

记录协议负责在传输连接上交换的所有底层消息,并且可以配置加密。每一条 TLS 记录以一个短标头开始。标头包含记录内容的类型 (或子协议)、协议版本和长度。原始消息经过分段 (或者合并)、压缩、添加认证码、加密转为 TLS 记录的数据部分。

分片 (Fragmentation)

记录层将信息块分割成携带 2^14 字节 (16KB) 或更小块的数据的 TLSPlaintext 记录。

记录协议传输由其他协议层提交给它的不透明数据缓冲区。如果缓冲区超过记录的长度限制(2^14),记录协议会将其切分成更小的片段。反过来也是可能的,属于同一个子协议的小缓冲区也可以组合成一个单独的记录。

struct {uint8 major, minor;
} ProtocolVersion;

enum {change_cipher_spec(20),alert(21),handshake(22),application_data(23), (255)
} ContentType;

struct {ContentType type; // 用于处理封闭片段的较高级协议ProtocolVersion version; // 使用的安全协议版本uint16 length; // TLSPlaintext.fragment 的长度(以字节为单位),不超过 2^14opaque fragment[TLSPlaintext.length]; // 透明的应用数据,被视为独立的块,由类型字段指定的较高级协议处理
} TLSPlaintext; 

记录压缩和解压缩 (Record compression and decompression)

压缩算法将 TLSPlaintext 结构转换为 TLSCompressed 结构。如果定义 CompressionMethod 为 null 表示不压缩

struct {ContentType type; // same as TLSPlaintext.typeProtocolVersion version; // same as TLSPlaintext.versionuint16 length; // TLSCompressed.fragment 的长度,不超过 2^14 + 1024opaque fragment[TLSCompressed.length];
} TLSCompressed; 

空或标准流加密 (Null or standard stream cipher)

流加密(BulkCipherAlgorithm)将 TLSCompressed.fragment 结构转换为流 TLSCiphertext.fragment 结构

stream-ciphered struct {opaque content[TLSCompressed.length];opaque MAC[CipherSpec.hash_size];
} GenericStreamCipher; 

MAC 产生方法如下:

HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment)); 

seq_num(记录的序列号)、hash(SecurityParameters.mac_algorithm 指定的哈希算法)

MAC(Message authentication code) - 消息认证码

注意,MAC 是在加密之前计算的。流加密加密整个块,包括 MAC。对于不使用同步向量 (例如 RC4) 的流加密,从一个记录结尾处的流加密状态仅用于后续数据包。如果 CipherSuite 是 TLS_NULL_WITH_NULL_NULL,则加密由身份操作 (数据未加密,MAC 大小为零,暗示不使用 MAC) 组成。TLSCiphertext.length 是 TLSCompressed.length 加上 CipherSpec.hash_size。

CBC 块加密 (分组加密)

块加密(如 RC2 或 DES),将 TLSCompressed.fragment 结构转换为块 TLSCiphertext.fragment 结构

block-ciphered struct {opaque content[TLSCompressed.length];opaque MAC[CipherSpec.hash_size];uint8 padding[GenericBlockCipher.padding_length];uint8 padding_length;
} GenericBlockCipher; 

padding: 添加的填充将明文长度强制为块密码块长度的整数倍。填充可以是长达 255 字节的任何长度,只要满足 TLSCiphertext.length 是块长度的整数倍。长度大于需要的值可以阻止基于分析交换信息长度的协议攻击。填充数据向量中的每个 uint8 必须填入填充长度值 (即 padding_length)。

padding_length: 填充长度应该使得 GenericBlockCipher 结构的总大小是加密块长度的倍数。合法值范围从零到 255(含)。该长度指定 padding_length 字段本身除外的填充字段的长度

加密块的数据长度(TLSCiphertext.length)是 TLSCompressed.length,CipherSpec.hash_size 和 padding_length 的总和加一

示例: 如果块长度为 8 字节,压缩内容长度(TLSCompressed.length)为 61 字节,MAC 长度为 20 字节,则填充前的长度为 82 字节(padding_length 占 1 字节)。 因此,为了使总长度为块长度 (8 字节) 的偶数倍,模 8 的填充长度必须等于 6,所以填充长度可以为 6,14,22 等。如果填充长度是需要的最小值,比如 6,填充将为 6 字节,每个块都包含值 6。因此,块加密之前的 GenericBlockCipher 的最后 8 个八位字节将为 xx 06 06 06 06 06 06 06,其中 xx 是 MAC 的最后一个八位字节。

XX- 06 06 06 06 06 06 - 06
MAC - padding[6]- padding_length 

记录有效载荷保护 (Record payload protection)

加密和 MAC 功能将 TLSCompressed 结构转换为 TLSCiphertext。记录的 MAC 还包括序列号,以便可以检测到丢失,额外或重复的消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值