- 浏览: 427778 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (433)
- 编程语言-JAVA/Scala/Clojure/Grovvy (86)
- 编程语言-C (227)
- 编程语言-Rust/C++/Objective-C/Objective-C++ (97)
- 编程语言-PHP (4)
- 编程语言-Perl (4)
- 编程语言-Javascript (6)
- 编程语言-Scheme/Lisp (9)
- 编程语言-lua (5)
- 编程语言-erl (4)
- 编程语言-go (4)
- 编程语言-Ruby (3)
- 编程语言-python (4)
- 编程语言-smalltalk (3)
- 编程语言-guile (3)
- 算法结构 (32)
- 多线程编程 (2)
- 网络编程 (7)
- 并发编程 (21)
- 并行编程 (2)
- 事务 (4)
- 架构/编程-模型/模式/思想 (6)
- 开发框架-Spring (2)
- 开发框架-ibatis (0)
- 开发框架-Struts (0)
- 开发框架-Hibernate (0)
- 开发框架-mybatis (0)
- 分布式 (38)
- 分布式存储 (10)
- 分布式文件系统-dfs (4)
- 分布式计算 (2)
- 分布式事务 (10)
- 分布式数据中间件 (1)
- 分布式服务框架 (12)
- rpc (8)
- 通信 (23)
- 电信 (3)
- 电商 (1)
- 互联网应用 (2)
- 大前端 (5)
- 第三方支付 (2)
- CSS (1)
- android (3)
- ios (0)
- html5 (0)
- kafka (0)
- memcached (2)
- nginx (1)
- 并行计算 (1)
- 实时计算 (0)
- Storm (0)
- 数据库 (7)
- mysql (6)
- oracle (3)
- redis (4)
- mongodb (2)
- hbase (1)
- dal (0)
- handoop (1)
- 机器学习-ML (3)
- 深度学习-DL (0)
- 神经网络 (0)
- netty (4)
- mina (0)
- 大数据 (7)
- 大数据-算法 (0)
- 大数据-框架&平台 (3)
- 人工智能 (7)
- 人工智能-算法 (4)
- 人工智能-框架&平台 (0)
- 协议 (42)
- 安全 (15)
- 消息队列 (2)
- os(linux、windows) (85)
最新评论
SSL
The Secure Sockets Layer (SSL) Protocol
目录
1 介绍 4
2 术语 4
3 文档术语 4
4 表述语言 4
4.1 基本快大小 4
4.2 Miscellaneous 4
4.3 向量 5
4.4 数值 5
4.5 枚举 6
4.6 构造类型 6
4.6.1 变体 6
4.7 加密属性 7
4.8 常量 7
5 SSL协议 7
5.1 会话/连接状态 8
5.2 记录层 9
5.2.1 分段 9
5.2.2 记录压缩及解压 9
5.2.3 记录有效载荷保护及加密规范 9
5.2.3.1 Null或标准流加密 10
5.2.3.2 CBC块加密 10
5.3 更新加密规范协议 10
5.4 告警协议 10
5.4.1 关闭告警 10
5.4.2 错误告警 10
5.5 握手协议概要 10
5.6 握手协议 11
5.6.1 Hello消息 11
5.6.1.1 Hello请求 11
5.6.1.2 客户端Hello 12
5.6.1.2.1 Random结构说明 12
5.6.1.2.2 ClientHello结构说明 14
5.6.1.3 服务器Hello 14
5.6.1.3.1 ServerHello结构说明 15
5.6.2 服务端证书 16
5.6.2.1 Certificate结构说明 16
5.6.3 服务端密钥(key)交换消息 16
5.6.3.1 ServerRSAParams结构说明 17
5.6.3.2 ServerDHParams结构说明 18
5.6.3.3 ServerFortezzaParams结构说明 18
5.6.3.4 ServerKeyExchange结构说明 18
5.6.3.5 Signature结构说明 19
5.6.4 证书请求 19
5.6.4.1 CertificateRequest结构说明 20
5.6.5 服务端Hello Done消息 20
5.6.6 客户端证书 20
5.6.7 客户端密钥(key)交换消息 20
5.6.7.1 RSA加密的Premaster Secret消息 21
5.6.7.2 FORTEZZA密钥(key)交换消息 21
5.6.7.3 客户端Diffie-Hellman公开值 21
5.6.8 证书验证 21
5.6.9 结束 21
5.7 应用程序数据协议 21
6 加密算法 22
6.1 非对称加密算法 22
6.1.1 RSA 22
6.1.2 Diffie-Hellman 23
6.1.3 FORTEZZA 23
6.2 对称加密算法和加密规范 23
6.2.1 主密钥(master secret) 24
6.2.2 将主密钥(master secret)转换为用于加密用的和MAC计算的密钥(key)和用于MAC计算的MAC Secrets 24
6.2.2.1 导出密钥生成例子 26
7 安全考虑 26
8 引用 26
1 介绍
2 术语
3 文档术语
4 表述语言
4.1 基本快大小
所有数据项的表示形式都是明确指定的。基本数据块的大小是一个字节(即,8位)。多字节数据项指的是字节的串联,从左到右,从上到下。在字节流中,一个多字节的项(一个数字的例子)形式(使用C标记法):
value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) | ...
| byte[n-1];
多字节值的字节序采用常用的网络字节序或大头序(big-endian)。
4.2 Miscellaneous
注释以“/*”开始,以“*/”结束。可选组件通过使用“[[ ]]”双中括号括起来表示。包含不被解释的数据的单字节实体是类型不透明的。
4.3 向量
一个向量就是一个一维数组,是一个由相同数据元素组成的流。向量的大小可能在编档的时候预先指定,也可能没有指定,直到运行时才给定一个大小。无论如何,向量长度声明的是字节数,而不是元素的数目。声明一个固定长度的向量,类型为T的新类型T'的语法为:
T T'[n];
这里,T'在数据流中占用n个字节,n是T的大小的倍数。向量的长度不包含在编码的流中。
opaque Datum[3]; /* three uninterpreted bytes */
Datum Data[9]; /* 3 consecutive 3 byte vectors */
4.4 数值
基本数值数据类型是一个无符号byte类型(uint8)。所有更大的数值数据类型采用固定长度的一系列连接的字节(在第4.1章节有描述)并且是无符号的。以下是预定义的数值类型。
uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];
4.5 枚举
枚举是另一个有效的稀疏数据类型。
enum { e1(v1), e2(v2), ... , en(vn), [[(n)]] } Te;
4.6 构造类型
为了方便,可以使用原始类型(基本类型)构造结构类型。每一个规范都声明了一个新的,唯一的类型。声明语法非常类似于C。
struct {
T1 f1;
T2 f2;
...
Tn fn;
} [[T]];
4.6.1 变体
struct {
T1 f1;
T2 f2;
....
Tn fn;
select (E) {
case e1: Te1;
case e2: Te2;
....
case en: Ten;
} [[fv]];
} [[Tv]];
例如:
enum { apple, orange } VariantTag;
struct {
uint16 number;
opaque string<0..10>; /* variable length */
} V1;
struct {
uint32 number;
opaque string[10]; /* fixed length */
} V2;
struct {
select (VariantTag) { /* value of selector is implicit */
case apple: V1; /* VariantBody, tag = apple */
case orange: V2; /* VariantBody, tag = orange */
} variant_body; /* optional label on variant */
} VariantRecord;
4.7 加密属性
4.8 常量
5 SSL协议
SSL是个分层协议,包括会话/连接层,记录层,。在每一层,消息可能包括长度、描述、内容字段。SSL将传输的消息数据分段放入管理的快中,可以对消息进行压缩,并应用MAC信息,并将加密处理后的结果进行传输,这个是可选的。接收的时候,对接收到的数据进行解密,验证,解压并重新组装后传给上层。
5.1 会话/连接状态
一个SSL会话是有状态的。这个是SSL握手协议的职责,握手协议协商客户端和服务器的状态,从而允许客户端和服务器的协议状态机保证操作一致,尽管事实上这个状态并不完全并行一致。这个状态逻辑上表现为两个状态,一次作为当前操作状态,再次(在握手协议期间)作为挂起状态。此外维护着单独的读/写状态。当客户端或服务器发送一个改变密钥规范的消息,客户端或服务器将挂起的写状态拷贝到当前的写状态。当握手协商完成后,客户端和服务器交换改变密钥规范的消息,然后使用新的约定的密钥规范进行通讯。
一个SSL会话可能包括多个安全连接;此外,双方可能有多个同时会话。
会话状态包括如下信息:
会话标识:
端证书:
压缩方式:
密钥规范:
主Secret:
是否可恢复:
连接状态包括如下信息:
服务器和客户端随机字节序列:
服务器写MAC secret:
客户端写MAC secret:
服务器写key:
客户端西key:
初始化向量:
5.2 记录层
5.2.1 分段
5.2.2 记录压缩及解压
5.2.3 记录有效载荷保护及加密规范
5.2.3.1 Null或标准流加密
5.2.3.2 CBC块加密
5.3 更新加密规范协议
5.4 告警协议
5.4.1 关闭告警
5.4.2 错误告警
5.5 握手协议概要
5.6 握手协议
SSL握手协议是SSL记录协议(SSL record protocol)定义的更高层次的客户端中的一个。该协议用于协商会话的安全属性。握手消息应用于SSL记录层(SSL record layer),SSL记录层(SSL record layer)将握手消息封装在一个或多个SSLPlaintext结构,并被当前活动的会话状态按照约定处理和传输。
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20), (255)
} HandshakeType;
5.6.1 Hello消息
5.6.1.1 Hello请求
服务器可能在任何时候向客户端发送Hello请求(hello request)消息,如果握手协议正在进行,客户端将忽略它。Hello请求只是一个简单的通知,客户端在适当的时候可以通过发送一个客户端Hello消息(client hello message)开始协商过程。
注意:由于握手协议被设计为优先于应用程序数据传输,要求协商开始于不超过最大长度应用程序数据消息的传输时间的一倍或两倍。
这个备注什么意思?
发送Hello请求之后,在随后的握手协商完成之前,服务器不可以重复请求。接收Hello请求的客户端如果处于握手协商状态(handshake negotiation state),应该简单的忽略这个消息。
Hello请求结构如下:
struct { } HelloRequest;
5.6.1.2 客户端Hello
当客户端第一次连接到服务器时,它需要(向服务器?)发送客户端Hello消息(client hello)作为其第一个消息。在一个现存的连接中,为了重新协商安全参数,客户端也可以发送一个客户端Hello消息来响应Hello请求(hello request)。这是一种被动协商,也可以主动协商,主动发送一个客户端Hello消息。客户端Hello消息包括一个Random结构(Random structure),这个随机结构(random structure)在这个协议过程后面会用到。
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
5.6.1.2.1 Random结构说明
Random结构只有两个字段,gmt_unix_time和random_bytes。
gmt_unix_time表示根据发送者的内部时钟,当前日期时间的标准Unix时间格式。时钟不要求正确的设置;上层或应用程序协议可能定义附加需求。
gmt_unix_time表示Unix日期时间,也就是Unix时间戳(Unix timestamp)、Unix时间(Unix time)或POSIX时间(POSIX time),表示为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。采用32位(4个字节)存储,采用32位格式,使用32位二进制数字表示。
random_bytes由安全随机数生成器生成,28字节。
客户端Hello消息包括一个变长的会话标识。如果不为空,这个值标识相同客户端和服务器(客户端希望重用安全参数的服务器)的一个会话。会话标识可能来自以前的一个连接,当前连接或者其他当前活动的连接。
加密套件列表,由客户端向服务器发送的客户端Hello消息中传递,包含客户端支持的以客户端的优先次序排序(第一选择)的加密算法组合。每个加密套件定义了包括一个密钥(key)交换算法和一个加密规范。服务器将选择一个加密套件,或者如果没有一个可接受的加密套件以供选择,返回一个握手失败告警,并关闭连接。
uint8 CipherSuite[2]; /* Cryptographic suite selector */
客户端Hello(Client Hello)包括一组客户端支持的压缩算法,同样根据客户端的优先次序排序。如果服务器不支持所有客户端指定的这些压缩算法,会话必须失败。
enum { null(0), (255) } CompressionMethod;
问题:支持哪些压缩算法正在调查中。
客户端Hello(Client Hello)结构如下:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-1>;
CompressionMethod compression_methods<1..2^8-1>;
} ClientHello;
5.6.1.2.2 ClientHello结构说明
client_version表示SSL协议版本,表示客户端在会话期间希望使用哪个版本进行通讯。这应该是客户端所支持的最新版本(最高值)版本。对于当前规范的版本,版本值为3.0。
random 客户端生成的一个Random结构(Random structure)
session_id 会话标识,表示客户端在当前连接上希望使用的会话标识。如果没有可用的会话标识,或者客户端希望生成新的安全参数,这个字段应该为空
cipher_suites一组加密套件,表示客户端支持的一组加密选项,按照客户端的优先次序排序(第一选择)。如果session_id字段不为空(标识一个会话恢复请求“session resumption request”),这个向量必须包含这个会话中的加密套件中的一个。这个字段的值在附录A.6中进行了定义。
compression_methods 压缩算法,表示客户端支持的一组压缩算法,按照客户端的优先次序排序。如果session_id字段不为空(标识一个会话恢复请求“session resumption request”),这个向量必须包含这个会话中的压缩算法中的一个。所有的SSL实现必须支持CompressionMethod.null
发送客户端Hello消息(client hello message)后,客户端等待一个服务器Hello消息(server hello message)。除了Hello请求(hello request),服务器返回的任何其他握手消息按严重错误处理。
SSL实现备注:
5.6.1.3 服务器Hello
服务器处理客户端Hello(client hello)消息,并返回握手失败告警或者服务器Hello(server hello)消息。
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
} ServerHello;
5.6.1.3.1 ServerHello结构说明
server_version 服务器版本,表示客户端发起的客户端Hello(client hello)消息中建议的版本中的低的那一个及服务器支持的版本中最高的一个。对于当前规范的版本,版本值为3.0。
random 服务器生成的Random结构,必须和客户端Hello中的random(ClientHello.random)不同。
session_id对应于当前连接的会话标识。如果客户端Hello中的session_id(ClientHello.session_id)不为空,服务器将从服务器维护的的会话中查询到匹配客户端Hello中的session_id(ClientHello.session_id)的session_id。如果发现有匹配的session_id,服务器将使用指定的会话状态建立新连接,服务器将返回客户端发送的客户端Hello中的session_id的值。这象征这一个会话恢复,并要求双方直接完成后面的消息。否则,该字段将包含新值以标识一个新的会话。服务器可能返回一个空的session_id,表示该会话将不会被缓存,同时不可以恢复。
cipher_suite 加密套件,从客户端发起的客户端Hello(Client Hello)消息中指定的那组加密套件(ClientHello.cipher_suites)中选择的一个加密套件。如果是恢复的会话,该字段就是恢复的会话状态中的加密套件。
compression_method 压缩算法,从客户端发起的客户端Hello(Client Hello)消息中指定的那组压缩算法(ClientHello.compression_methods)中选择的一个压缩算法。如果是恢复的会话,该字段就是恢复的会话状态中的压缩算法。
5.6.2 服务端证书
如果服务器要求认证(通常是这种情况),服务器在返回服务器Hello(server hello)消息后立即发送服务器的证书。证书类型必须适合所选择的密码套件的密钥交换算法,通常是一个x.509.v3证书(或者如果是FORTEZZA(tm) [FOR]的情况,就应该是改进的X.509证书)。如果是一个证书请求消息,则通过证书请求响应消息类型返回服务器证书。
opaque ASN.1Cert<1..2^24-1>;
struct {
ASN.1Cert certificate_list<1..2^24-1>;
} Certificate;
5.6.2.1 Certificate结构说明
Certificate结构中只有一个certificate_list字段。
certificate_list 一组证书列表,每个证书表示一个证书序列(也就是一个证书链)。第一个是发送者的证书,后跟任何证书颁发机构颁发的证书(顺序按颁发机构的级别依次往上)。
5.6.3 服务端密钥(key)交换消息
如果服务器没有证书,或者只有一个用于签名的证书(例如DSS证书, 只签名的RSA证书),或者采用的是FORTEZZA(一种PCMCIA卡)的密钥交换算法,但密钥交换已经使用,服务器发送服务器密钥交换消息(server key exchange message)。如果服务器证书包含Diffie-Hellman [DH1 ]参数,这个消息不会用到。
enum { rsa, diffie_hellman, fortezza_kea }
KeyExchangeAlgorithm;
struct {
opaque rsa_modulus<1..2^16-1>;
opaque rsa_exponent<1..2^16-1>;
} ServerRSAParams;
备注:DSS(Digital Signature Standard, 数字签名标准),由美国国家标准与技术研究所(National Institute of Standards and Technology U.S. Department of Commerce)于1994年5月制定。
备注:PCMCIA(Personal Computer Memory Card International Association,PC机内存卡国际联合会),是一个成立于1989年的国际性组织,是一个有300多个成员公司的国际标准组织和贸易联合会。该组织主要是建立一个省电、小体积的整合性电子卡片的标准,也就是PCMCIA卡。
备注:PCMCIA卡是一种提供加密和数字签名的卡。
备注:FORTEZZA,就是一种PCMCIA卡,提供加密和数字签名。
备注:KEA(Key Exchange Algorithm,密钥交换算法)
备注:Diffie-Hellman,DH1,由Diffie, W. and M. Hellman于June 1977发表的论文:密码学的新方向(New Directions in Cryptography)。在网上没有找到比较权威的文档引用地址。
5.6.3.1 ServerRSAParams结构说明
ServerRSAParams结构包括两个字段。
rsa_modulus 服务器的临时RSA密钥模块
rsa_exponent服务器的临时RSA密钥模块的public组件。
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams; /* Ephemeral DH parameters */
5.6.3.2 ServerDHParams结构说明
ServerDHParams结构包括3个字段。
dh_p
dh_g
dh_Ys
struct {
opaque r_s [128];
} ServerFortezzaParams;
5.6.3.3 ServerFortezzaParams结构说明
ServerFortezzaParams结构只包含一个r_s字段。
r_s
struct {
select (KeyExchangeAlgorithm) {
case diffie_hellman:
ServerDHParams params;
Signature signed_params;
case rsa:
ServerRSAParams params;
Signature signed_params;
case fortezza_kea:
ServerFortezzaParams params;
};
} ServerKeyExchange;
5.6.3.4 ServerKeyExchange结构说明
params
signed_params
enum { anonymous, rsa, dsa } SignatureAlgorithm;
digitally-signed struct {
select(SignatureAlgorithm) {
case anonymous: struct { };
case rsa:
opaque md5_hash[16];
opaque sha_hash[20];
case dsa:
opaque sha_hash[20];
};
} Signature;
5.6.3.5 Signature结构说明
md5_hash
sha_hash
5.6.4 证书请求
对于已选择的加密套件,如果合适的话,一个非匿名的服务器可以选择从客户端请求一个证书。
enum {
rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
rsa_ephemeral_dh(5), dss_ephemeral_dh(6), fortezza_kea(20),
(255)
} ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
struct {
ClientCertificateType certificate_types<1..2^8-1>;
DistinguishedName certificate_authorities<3..2^16-1>;
} CertificateRequest;
5.6.4.1 CertificateRequest结构说明
certificate_types
certificate_authorities
备注:DistinguishedName源自X509
备注:匿名服务器请求客户端标识是个严重的handshake_failure告警
5.6.5 服务端Hello Done消息
服务器Hello Done消息由服务器发送,用于结束服务器Hello(server hello)以及相关联的消息。该消息发送后,服务器将等待客户端的响应。
struct { } ServerHelloDone;
当收到服务器Hello Done消息(server hello done message)时,如果必要的话,客户端应该验证服务器提供的证书的有效性,并检查服务器Hello(server hello)参数是否可接受。
5.6.6 客户端证书
5.6.7 客户端密钥(key)交换消息
5.6.7.1 RSA加密的Premaster Secret消息
5.6.7.2 FORTEZZA密钥(key)交换消息
5.6.7.3 客户端Diffie-Hellman公开值
5.6.8 证书验证
5.6.9 结束
5.7 应用程序数据协议
6 加密算法
密钥交换,认证,加密以及MAC算法由服务器选择的加密套件确定,并反映在服务器Hello消息(server hello message)中。
6.1 非对称加密算法
在握手协议中使用的非对称算法来进行身份验证,并生成共享密钥(key和secret)。
对于Diffie-Hellman, RSA, and FORTEZZA,使用相同的算法将pre_master_secret转换为master_secret。一旦master_secret被计算出来,pre_master_secret应该从内存中删除。
master_secret =
MD5(pre_master_secret + SHA('A' + pre_master_secret +
ClientHello.random + ServerHello.random)) +
MD5(pre_master_secret + SHA('BB' + pre_master_secret +
ClientHello.random + ServerHello.random)) +
MD5(pre_master_secret + SHA('CCC' + pre_master_secret +
ClientHello.random + ServerHello.random));
6.1.1 RSA
如果服务器采用RSA进行认证和密钥交换,客户端生成一个48字节的pre_master_secret,使用服务器的公钥进行加密,并发送给服务器。服务器使用私钥解密pre_master_secret。然后服务器/客户端分别按照上面的规定将pre_master_secret转换为master_secret。
使用PKCS #1 [PKCS1] 1类型块进行RSA数字签名。使用PKCS #1 2类型快进行RAS公钥加密。
6.1.2 Diffie-Hellman
执行一个约定的Diffie-Hellman计算。pre_master_secret作为协商的密钥(Z),并按照上面的规定将pre_master_secret转换为master_secret。
备注:Diffie-Hellman参数由服务器指定,它可能包含在服务器证书里边(持久),也可能用完就丢(不会持久)。
6.1.3 FORTEZZA
FORTEZZA指的是一种PCMCIA卡,提供加密和数字签名。
一个随机的48字节的pre_master_secret被发送(使用TEK及IV加密)。服务器解密pre_master_secret,并按照上面的规定将pre_master_secret转换为master_secret。用于加密的块加密密钥和初始化向量由客户端的token生成并通过密钥交换消息(key exchange message)交换。master_secret只用于MAC计算
备注: TEK(token encryption key),一种加密密钥
备注:IV(Initialization Vector),初始化向量。当块加密用于CBC模式,在加密前,初始化向量和第一个明文块是异或的。
6.2 对称加密算法和加密规范
该技术用于加密和验证当前活动加密规范指定的SSL记录完整性。使用DES加密数据,使用MD5生成认证码就是个典型的例子。在开始SSL握手协议时,如果加密和MAC算法设置为SSL_NULL_WITH_NULL_NULL,表示不需要进行消息认证和加密。握手协议用于协商一个更安全的加密规范和生成一个加密密钥。
6.2.1 主密钥(master secret)
在对记录(record)进行安全加密和完整性验证之前,客户端和服务器需要生成只有自己知道的共享密钥信息。这个值为48字节长度,被称为主密钥(master secret)。主密钥(master secret)用于生成用于加密用的和MAC计算的密钥(key)和密钥(secret)。有些算法(如FORTEZZA)可能有他们自己的加密密钥生成过程(对于FORTEZZA,主密钥“master secret”只用于MAC计算)。
6.2.2 将主密钥(master secret)转换为用于加密用的和MAC计算的密钥(key)和用于MAC计算的MAC Secrets
主密钥(master secret)被散列到一个安全的字节序列,当前加密规范要求,主密钥(master secret)被分配给MAC密钥(secret),密钥(key)以及非输出的初始化向量(IV)。加密规范要求按照如下顺序从主密钥(master secret)生成:客户端写入MAC密钥(client write MAC secret),服务器写入MAC密钥(server write MAC secret),客户端写入密钥(client write key),服务器写入密钥(server write key),客户端写入初始化向量(client write IV)和服务器写入初始化向量(server write IV)。无用的值,如密钥交换消息(KeyExchange message)通讯的FORTEZZA密钥(key),指定为空值。以下输入是有效的密钥(key)定义过程:
opaque MasterSecret[48]
ClientHello.random
ServerHello.random
这里的客户端写入MAC密钥(client write MAC secret)是什么?服务器写入MAC密钥(server write MAC secret)又是什么?还有客户端写入密钥(client write key)、服务器写入密钥(server write key)、客户端写入初始化向量(client write IV)和服务器写入初始化向量(server write IV),都是些什么?
为了生成密钥(key)资料,计算:
key_block =
MD5(master_secret + SHA(`A' + master_secret +
ServerHello.random +
ClientHello.random)) +
MD5(master_secret + SHA(`BB' + master_secret +
ServerHello.random +
ClientHello.random)) +
MD5(master_secret + SHA(`CCC' + master_secret +
ServerHello.random +
ClientHello.random)) + [...];
直到生成足够的输出。然后,key_block按照如下方式划分分段。
client_write_MAC_secret[CipherSpec.hash_size]
server_write_MAC_secret[CipherSpec.hash_size]
client_write_key[CipherSpec.key_material]
server_write_key[CipherSpec.key_material]
client_write_IV[CipherSpec.IV_size] /* non-export ciphers */
server_write_IV[CipherSpec.IV_size] /* non-export ciphers */
任何额外的key_block资料会被丢弃。
可导出的加密算法(CipherSpec.is_exportable为true)需要如下额外的处理以导出它们最终的写密钥(write key)
final_client_write_key = MD5(client_write_key +
ClientHello.random +
ServerHello.random);
final_server_write_key = MD5(server_write_key +
ServerHello.random +
ClientHello.random);
这里的写密钥(write key)又是什么?上面的客户端写入密钥(client write key)、服务器写入密钥(server write key)应该就是指的这里的写密钥(write key)。
可导出的加密算法从random消息中导出它们的初始化向量(IV):
client_write_IV = MD5(ClientHello.random + ServerHello.random);
server_write_IV = MD5(ServerHello.random + ClientHello.random);
MD5输出通过丢弃最少的有用字节来修剪至一个合适的大小。
6.2.2.1 导出密钥生成例子
7 安全考虑
8 引用
1、 The Secure Sockets Layer (SSL) Protocol Version 3.0, http://www.rfc-base.org/rfc-6101.html
2、 The Secure Sockets Layer (SSL) Protocol Version 3.0, http://www.rfc-base.org/txt/rfc-6101.txt
3、 The TLS Protocol Version 1.0, http://www.ietf.org/rfc/rfc2246.txt
4、 The Secure Sockets Layer (SSL) Protocol Version 3.0, https://www.rfc-editor.org/rfc/rfc6101.txt
5、 Asymmetric-Key Cryptography, http://www.cs.cornell.edu/courses/CS5430/2013sp/TL04.asymmetric.html
The Secure Sockets Layer (SSL) Protocol
目录
1 介绍 4
2 术语 4
3 文档术语 4
4 表述语言 4
4.1 基本快大小 4
4.2 Miscellaneous 4
4.3 向量 5
4.4 数值 5
4.5 枚举 6
4.6 构造类型 6
4.6.1 变体 6
4.7 加密属性 7
4.8 常量 7
5 SSL协议 7
5.1 会话/连接状态 8
5.2 记录层 9
5.2.1 分段 9
5.2.2 记录压缩及解压 9
5.2.3 记录有效载荷保护及加密规范 9
5.2.3.1 Null或标准流加密 10
5.2.3.2 CBC块加密 10
5.3 更新加密规范协议 10
5.4 告警协议 10
5.4.1 关闭告警 10
5.4.2 错误告警 10
5.5 握手协议概要 10
5.6 握手协议 11
5.6.1 Hello消息 11
5.6.1.1 Hello请求 11
5.6.1.2 客户端Hello 12
5.6.1.2.1 Random结构说明 12
5.6.1.2.2 ClientHello结构说明 14
5.6.1.3 服务器Hello 14
5.6.1.3.1 ServerHello结构说明 15
5.6.2 服务端证书 16
5.6.2.1 Certificate结构说明 16
5.6.3 服务端密钥(key)交换消息 16
5.6.3.1 ServerRSAParams结构说明 17
5.6.3.2 ServerDHParams结构说明 18
5.6.3.3 ServerFortezzaParams结构说明 18
5.6.3.4 ServerKeyExchange结构说明 18
5.6.3.5 Signature结构说明 19
5.6.4 证书请求 19
5.6.4.1 CertificateRequest结构说明 20
5.6.5 服务端Hello Done消息 20
5.6.6 客户端证书 20
5.6.7 客户端密钥(key)交换消息 20
5.6.7.1 RSA加密的Premaster Secret消息 21
5.6.7.2 FORTEZZA密钥(key)交换消息 21
5.6.7.3 客户端Diffie-Hellman公开值 21
5.6.8 证书验证 21
5.6.9 结束 21
5.7 应用程序数据协议 21
6 加密算法 22
6.1 非对称加密算法 22
6.1.1 RSA 22
6.1.2 Diffie-Hellman 23
6.1.3 FORTEZZA 23
6.2 对称加密算法和加密规范 23
6.2.1 主密钥(master secret) 24
6.2.2 将主密钥(master secret)转换为用于加密用的和MAC计算的密钥(key)和用于MAC计算的MAC Secrets 24
6.2.2.1 导出密钥生成例子 26
7 安全考虑 26
8 引用 26
1 介绍
2 术语
3 文档术语
4 表述语言
4.1 基本快大小
所有数据项的表示形式都是明确指定的。基本数据块的大小是一个字节(即,8位)。多字节数据项指的是字节的串联,从左到右,从上到下。在字节流中,一个多字节的项(一个数字的例子)形式(使用C标记法):
value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) | ...
| byte[n-1];
多字节值的字节序采用常用的网络字节序或大头序(big-endian)。
4.2 Miscellaneous
注释以“/*”开始,以“*/”结束。可选组件通过使用“[[ ]]”双中括号括起来表示。包含不被解释的数据的单字节实体是类型不透明的。
4.3 向量
一个向量就是一个一维数组,是一个由相同数据元素组成的流。向量的大小可能在编档的时候预先指定,也可能没有指定,直到运行时才给定一个大小。无论如何,向量长度声明的是字节数,而不是元素的数目。声明一个固定长度的向量,类型为T的新类型T'的语法为:
T T'[n];
这里,T'在数据流中占用n个字节,n是T的大小的倍数。向量的长度不包含在编码的流中。
opaque Datum[3]; /* three uninterpreted bytes */
Datum Data[9]; /* 3 consecutive 3 byte vectors */
4.4 数值
基本数值数据类型是一个无符号byte类型(uint8)。所有更大的数值数据类型采用固定长度的一系列连接的字节(在第4.1章节有描述)并且是无符号的。以下是预定义的数值类型。
uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];
4.5 枚举
枚举是另一个有效的稀疏数据类型。
enum { e1(v1), e2(v2), ... , en(vn), [[(n)]] } Te;
4.6 构造类型
为了方便,可以使用原始类型(基本类型)构造结构类型。每一个规范都声明了一个新的,唯一的类型。声明语法非常类似于C。
struct {
T1 f1;
T2 f2;
...
Tn fn;
} [[T]];
4.6.1 变体
struct {
T1 f1;
T2 f2;
....
Tn fn;
select (E) {
case e1: Te1;
case e2: Te2;
....
case en: Ten;
} [[fv]];
} [[Tv]];
例如:
enum { apple, orange } VariantTag;
struct {
uint16 number;
opaque string<0..10>; /* variable length */
} V1;
struct {
uint32 number;
opaque string[10]; /* fixed length */
} V2;
struct {
select (VariantTag) { /* value of selector is implicit */
case apple: V1; /* VariantBody, tag = apple */
case orange: V2; /* VariantBody, tag = orange */
} variant_body; /* optional label on variant */
} VariantRecord;
4.7 加密属性
4.8 常量
5 SSL协议
SSL是个分层协议,包括会话/连接层,记录层,。在每一层,消息可能包括长度、描述、内容字段。SSL将传输的消息数据分段放入管理的快中,可以对消息进行压缩,并应用MAC信息,并将加密处理后的结果进行传输,这个是可选的。接收的时候,对接收到的数据进行解密,验证,解压并重新组装后传给上层。
5.1 会话/连接状态
一个SSL会话是有状态的。这个是SSL握手协议的职责,握手协议协商客户端和服务器的状态,从而允许客户端和服务器的协议状态机保证操作一致,尽管事实上这个状态并不完全并行一致。这个状态逻辑上表现为两个状态,一次作为当前操作状态,再次(在握手协议期间)作为挂起状态。此外维护着单独的读/写状态。当客户端或服务器发送一个改变密钥规范的消息,客户端或服务器将挂起的写状态拷贝到当前的写状态。当握手协商完成后,客户端和服务器交换改变密钥规范的消息,然后使用新的约定的密钥规范进行通讯。
一个SSL会话可能包括多个安全连接;此外,双方可能有多个同时会话。
会话状态包括如下信息:
会话标识:
端证书:
压缩方式:
密钥规范:
主Secret:
是否可恢复:
连接状态包括如下信息:
服务器和客户端随机字节序列:
服务器写MAC secret:
客户端写MAC secret:
服务器写key:
客户端西key:
初始化向量:
5.2 记录层
5.2.1 分段
5.2.2 记录压缩及解压
5.2.3 记录有效载荷保护及加密规范
5.2.3.1 Null或标准流加密
5.2.3.2 CBC块加密
5.3 更新加密规范协议
5.4 告警协议
5.4.1 关闭告警
5.4.2 错误告警
5.5 握手协议概要
5.6 握手协议
SSL握手协议是SSL记录协议(SSL record protocol)定义的更高层次的客户端中的一个。该协议用于协商会话的安全属性。握手消息应用于SSL记录层(SSL record layer),SSL记录层(SSL record layer)将握手消息封装在一个或多个SSLPlaintext结构,并被当前活动的会话状态按照约定处理和传输。
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20), (255)
} HandshakeType;
5.6.1 Hello消息
5.6.1.1 Hello请求
服务器可能在任何时候向客户端发送Hello请求(hello request)消息,如果握手协议正在进行,客户端将忽略它。Hello请求只是一个简单的通知,客户端在适当的时候可以通过发送一个客户端Hello消息(client hello message)开始协商过程。
注意:由于握手协议被设计为优先于应用程序数据传输,要求协商开始于不超过最大长度应用程序数据消息的传输时间的一倍或两倍。
这个备注什么意思?
发送Hello请求之后,在随后的握手协商完成之前,服务器不可以重复请求。接收Hello请求的客户端如果处于握手协商状态(handshake negotiation state),应该简单的忽略这个消息。
Hello请求结构如下:
struct { } HelloRequest;
5.6.1.2 客户端Hello
当客户端第一次连接到服务器时,它需要(向服务器?)发送客户端Hello消息(client hello)作为其第一个消息。在一个现存的连接中,为了重新协商安全参数,客户端也可以发送一个客户端Hello消息来响应Hello请求(hello request)。这是一种被动协商,也可以主动协商,主动发送一个客户端Hello消息。客户端Hello消息包括一个Random结构(Random structure),这个随机结构(random structure)在这个协议过程后面会用到。
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
5.6.1.2.1 Random结构说明
Random结构只有两个字段,gmt_unix_time和random_bytes。
gmt_unix_time表示根据发送者的内部时钟,当前日期时间的标准Unix时间格式。时钟不要求正确的设置;上层或应用程序协议可能定义附加需求。
gmt_unix_time表示Unix日期时间,也就是Unix时间戳(Unix timestamp)、Unix时间(Unix time)或POSIX时间(POSIX time),表示为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。采用32位(4个字节)存储,采用32位格式,使用32位二进制数字表示。
random_bytes由安全随机数生成器生成,28字节。
客户端Hello消息包括一个变长的会话标识。如果不为空,这个值标识相同客户端和服务器(客户端希望重用安全参数的服务器)的一个会话。会话标识可能来自以前的一个连接,当前连接或者其他当前活动的连接。
加密套件列表,由客户端向服务器发送的客户端Hello消息中传递,包含客户端支持的以客户端的优先次序排序(第一选择)的加密算法组合。每个加密套件定义了包括一个密钥(key)交换算法和一个加密规范。服务器将选择一个加密套件,或者如果没有一个可接受的加密套件以供选择,返回一个握手失败告警,并关闭连接。
uint8 CipherSuite[2]; /* Cryptographic suite selector */
客户端Hello(Client Hello)包括一组客户端支持的压缩算法,同样根据客户端的优先次序排序。如果服务器不支持所有客户端指定的这些压缩算法,会话必须失败。
enum { null(0), (255) } CompressionMethod;
问题:支持哪些压缩算法正在调查中。
客户端Hello(Client Hello)结构如下:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-1>;
CompressionMethod compression_methods<1..2^8-1>;
} ClientHello;
5.6.1.2.2 ClientHello结构说明
client_version表示SSL协议版本,表示客户端在会话期间希望使用哪个版本进行通讯。这应该是客户端所支持的最新版本(最高值)版本。对于当前规范的版本,版本值为3.0。
random 客户端生成的一个Random结构(Random structure)
session_id 会话标识,表示客户端在当前连接上希望使用的会话标识。如果没有可用的会话标识,或者客户端希望生成新的安全参数,这个字段应该为空
cipher_suites一组加密套件,表示客户端支持的一组加密选项,按照客户端的优先次序排序(第一选择)。如果session_id字段不为空(标识一个会话恢复请求“session resumption request”),这个向量必须包含这个会话中的加密套件中的一个。这个字段的值在附录A.6中进行了定义。
compression_methods 压缩算法,表示客户端支持的一组压缩算法,按照客户端的优先次序排序。如果session_id字段不为空(标识一个会话恢复请求“session resumption request”),这个向量必须包含这个会话中的压缩算法中的一个。所有的SSL实现必须支持CompressionMethod.null
发送客户端Hello消息(client hello message)后,客户端等待一个服务器Hello消息(server hello message)。除了Hello请求(hello request),服务器返回的任何其他握手消息按严重错误处理。
SSL实现备注:
5.6.1.3 服务器Hello
服务器处理客户端Hello(client hello)消息,并返回握手失败告警或者服务器Hello(server hello)消息。
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
} ServerHello;
5.6.1.3.1 ServerHello结构说明
server_version 服务器版本,表示客户端发起的客户端Hello(client hello)消息中建议的版本中的低的那一个及服务器支持的版本中最高的一个。对于当前规范的版本,版本值为3.0。
random 服务器生成的Random结构,必须和客户端Hello中的random(ClientHello.random)不同。
session_id对应于当前连接的会话标识。如果客户端Hello中的session_id(ClientHello.session_id)不为空,服务器将从服务器维护的的会话中查询到匹配客户端Hello中的session_id(ClientHello.session_id)的session_id。如果发现有匹配的session_id,服务器将使用指定的会话状态建立新连接,服务器将返回客户端发送的客户端Hello中的session_id的值。这象征这一个会话恢复,并要求双方直接完成后面的消息。否则,该字段将包含新值以标识一个新的会话。服务器可能返回一个空的session_id,表示该会话将不会被缓存,同时不可以恢复。
cipher_suite 加密套件,从客户端发起的客户端Hello(Client Hello)消息中指定的那组加密套件(ClientHello.cipher_suites)中选择的一个加密套件。如果是恢复的会话,该字段就是恢复的会话状态中的加密套件。
compression_method 压缩算法,从客户端发起的客户端Hello(Client Hello)消息中指定的那组压缩算法(ClientHello.compression_methods)中选择的一个压缩算法。如果是恢复的会话,该字段就是恢复的会话状态中的压缩算法。
5.6.2 服务端证书
如果服务器要求认证(通常是这种情况),服务器在返回服务器Hello(server hello)消息后立即发送服务器的证书。证书类型必须适合所选择的密码套件的密钥交换算法,通常是一个x.509.v3证书(或者如果是FORTEZZA(tm) [FOR]的情况,就应该是改进的X.509证书)。如果是一个证书请求消息,则通过证书请求响应消息类型返回服务器证书。
opaque ASN.1Cert<1..2^24-1>;
struct {
ASN.1Cert certificate_list<1..2^24-1>;
} Certificate;
5.6.2.1 Certificate结构说明
Certificate结构中只有一个certificate_list字段。
certificate_list 一组证书列表,每个证书表示一个证书序列(也就是一个证书链)。第一个是发送者的证书,后跟任何证书颁发机构颁发的证书(顺序按颁发机构的级别依次往上)。
5.6.3 服务端密钥(key)交换消息
如果服务器没有证书,或者只有一个用于签名的证书(例如DSS证书, 只签名的RSA证书),或者采用的是FORTEZZA(一种PCMCIA卡)的密钥交换算法,但密钥交换已经使用,服务器发送服务器密钥交换消息(server key exchange message)。如果服务器证书包含Diffie-Hellman [DH1 ]参数,这个消息不会用到。
enum { rsa, diffie_hellman, fortezza_kea }
KeyExchangeAlgorithm;
struct {
opaque rsa_modulus<1..2^16-1>;
opaque rsa_exponent<1..2^16-1>;
} ServerRSAParams;
备注:DSS(Digital Signature Standard, 数字签名标准),由美国国家标准与技术研究所(National Institute of Standards and Technology U.S. Department of Commerce)于1994年5月制定。
备注:PCMCIA(Personal Computer Memory Card International Association,PC机内存卡国际联合会),是一个成立于1989年的国际性组织,是一个有300多个成员公司的国际标准组织和贸易联合会。该组织主要是建立一个省电、小体积的整合性电子卡片的标准,也就是PCMCIA卡。
备注:PCMCIA卡是一种提供加密和数字签名的卡。
备注:FORTEZZA,就是一种PCMCIA卡,提供加密和数字签名。
备注:KEA(Key Exchange Algorithm,密钥交换算法)
备注:Diffie-Hellman,DH1,由Diffie, W. and M. Hellman于June 1977发表的论文:密码学的新方向(New Directions in Cryptography)。在网上没有找到比较权威的文档引用地址。
5.6.3.1 ServerRSAParams结构说明
ServerRSAParams结构包括两个字段。
rsa_modulus 服务器的临时RSA密钥模块
rsa_exponent服务器的临时RSA密钥模块的public组件。
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams; /* Ephemeral DH parameters */
5.6.3.2 ServerDHParams结构说明
ServerDHParams结构包括3个字段。
dh_p
dh_g
dh_Ys
struct {
opaque r_s [128];
} ServerFortezzaParams;
5.6.3.3 ServerFortezzaParams结构说明
ServerFortezzaParams结构只包含一个r_s字段。
r_s
struct {
select (KeyExchangeAlgorithm) {
case diffie_hellman:
ServerDHParams params;
Signature signed_params;
case rsa:
ServerRSAParams params;
Signature signed_params;
case fortezza_kea:
ServerFortezzaParams params;
};
} ServerKeyExchange;
5.6.3.4 ServerKeyExchange结构说明
params
signed_params
enum { anonymous, rsa, dsa } SignatureAlgorithm;
digitally-signed struct {
select(SignatureAlgorithm) {
case anonymous: struct { };
case rsa:
opaque md5_hash[16];
opaque sha_hash[20];
case dsa:
opaque sha_hash[20];
};
} Signature;
5.6.3.5 Signature结构说明
md5_hash
sha_hash
5.6.4 证书请求
对于已选择的加密套件,如果合适的话,一个非匿名的服务器可以选择从客户端请求一个证书。
enum {
rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
rsa_ephemeral_dh(5), dss_ephemeral_dh(6), fortezza_kea(20),
(255)
} ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
struct {
ClientCertificateType certificate_types<1..2^8-1>;
DistinguishedName certificate_authorities<3..2^16-1>;
} CertificateRequest;
5.6.4.1 CertificateRequest结构说明
certificate_types
certificate_authorities
备注:DistinguishedName源自X509
备注:匿名服务器请求客户端标识是个严重的handshake_failure告警
5.6.5 服务端Hello Done消息
服务器Hello Done消息由服务器发送,用于结束服务器Hello(server hello)以及相关联的消息。该消息发送后,服务器将等待客户端的响应。
struct { } ServerHelloDone;
当收到服务器Hello Done消息(server hello done message)时,如果必要的话,客户端应该验证服务器提供的证书的有效性,并检查服务器Hello(server hello)参数是否可接受。
5.6.6 客户端证书
5.6.7 客户端密钥(key)交换消息
5.6.7.1 RSA加密的Premaster Secret消息
5.6.7.2 FORTEZZA密钥(key)交换消息
5.6.7.3 客户端Diffie-Hellman公开值
5.6.8 证书验证
5.6.9 结束
5.7 应用程序数据协议
6 加密算法
密钥交换,认证,加密以及MAC算法由服务器选择的加密套件确定,并反映在服务器Hello消息(server hello message)中。
6.1 非对称加密算法
在握手协议中使用的非对称算法来进行身份验证,并生成共享密钥(key和secret)。
对于Diffie-Hellman, RSA, and FORTEZZA,使用相同的算法将pre_master_secret转换为master_secret。一旦master_secret被计算出来,pre_master_secret应该从内存中删除。
master_secret =
MD5(pre_master_secret + SHA('A' + pre_master_secret +
ClientHello.random + ServerHello.random)) +
MD5(pre_master_secret + SHA('BB' + pre_master_secret +
ClientHello.random + ServerHello.random)) +
MD5(pre_master_secret + SHA('CCC' + pre_master_secret +
ClientHello.random + ServerHello.random));
6.1.1 RSA
如果服务器采用RSA进行认证和密钥交换,客户端生成一个48字节的pre_master_secret,使用服务器的公钥进行加密,并发送给服务器。服务器使用私钥解密pre_master_secret。然后服务器/客户端分别按照上面的规定将pre_master_secret转换为master_secret。
使用PKCS #1 [PKCS1] 1类型块进行RSA数字签名。使用PKCS #1 2类型快进行RAS公钥加密。
6.1.2 Diffie-Hellman
执行一个约定的Diffie-Hellman计算。pre_master_secret作为协商的密钥(Z),并按照上面的规定将pre_master_secret转换为master_secret。
备注:Diffie-Hellman参数由服务器指定,它可能包含在服务器证书里边(持久),也可能用完就丢(不会持久)。
6.1.3 FORTEZZA
FORTEZZA指的是一种PCMCIA卡,提供加密和数字签名。
一个随机的48字节的pre_master_secret被发送(使用TEK及IV加密)。服务器解密pre_master_secret,并按照上面的规定将pre_master_secret转换为master_secret。用于加密的块加密密钥和初始化向量由客户端的token生成并通过密钥交换消息(key exchange message)交换。master_secret只用于MAC计算
备注: TEK(token encryption key),一种加密密钥
备注:IV(Initialization Vector),初始化向量。当块加密用于CBC模式,在加密前,初始化向量和第一个明文块是异或的。
6.2 对称加密算法和加密规范
该技术用于加密和验证当前活动加密规范指定的SSL记录完整性。使用DES加密数据,使用MD5生成认证码就是个典型的例子。在开始SSL握手协议时,如果加密和MAC算法设置为SSL_NULL_WITH_NULL_NULL,表示不需要进行消息认证和加密。握手协议用于协商一个更安全的加密规范和生成一个加密密钥。
6.2.1 主密钥(master secret)
在对记录(record)进行安全加密和完整性验证之前,客户端和服务器需要生成只有自己知道的共享密钥信息。这个值为48字节长度,被称为主密钥(master secret)。主密钥(master secret)用于生成用于加密用的和MAC计算的密钥(key)和密钥(secret)。有些算法(如FORTEZZA)可能有他们自己的加密密钥生成过程(对于FORTEZZA,主密钥“master secret”只用于MAC计算)。
6.2.2 将主密钥(master secret)转换为用于加密用的和MAC计算的密钥(key)和用于MAC计算的MAC Secrets
主密钥(master secret)被散列到一个安全的字节序列,当前加密规范要求,主密钥(master secret)被分配给MAC密钥(secret),密钥(key)以及非输出的初始化向量(IV)。加密规范要求按照如下顺序从主密钥(master secret)生成:客户端写入MAC密钥(client write MAC secret),服务器写入MAC密钥(server write MAC secret),客户端写入密钥(client write key),服务器写入密钥(server write key),客户端写入初始化向量(client write IV)和服务器写入初始化向量(server write IV)。无用的值,如密钥交换消息(KeyExchange message)通讯的FORTEZZA密钥(key),指定为空值。以下输入是有效的密钥(key)定义过程:
opaque MasterSecret[48]
ClientHello.random
ServerHello.random
这里的客户端写入MAC密钥(client write MAC secret)是什么?服务器写入MAC密钥(server write MAC secret)又是什么?还有客户端写入密钥(client write key)、服务器写入密钥(server write key)、客户端写入初始化向量(client write IV)和服务器写入初始化向量(server write IV),都是些什么?
为了生成密钥(key)资料,计算:
key_block =
MD5(master_secret + SHA(`A' + master_secret +
ServerHello.random +
ClientHello.random)) +
MD5(master_secret + SHA(`BB' + master_secret +
ServerHello.random +
ClientHello.random)) +
MD5(master_secret + SHA(`CCC' + master_secret +
ServerHello.random +
ClientHello.random)) + [...];
直到生成足够的输出。然后,key_block按照如下方式划分分段。
client_write_MAC_secret[CipherSpec.hash_size]
server_write_MAC_secret[CipherSpec.hash_size]
client_write_key[CipherSpec.key_material]
server_write_key[CipherSpec.key_material]
client_write_IV[CipherSpec.IV_size] /* non-export ciphers */
server_write_IV[CipherSpec.IV_size] /* non-export ciphers */
任何额外的key_block资料会被丢弃。
可导出的加密算法(CipherSpec.is_exportable为true)需要如下额外的处理以导出它们最终的写密钥(write key)
final_client_write_key = MD5(client_write_key +
ClientHello.random +
ServerHello.random);
final_server_write_key = MD5(server_write_key +
ServerHello.random +
ClientHello.random);
这里的写密钥(write key)又是什么?上面的客户端写入密钥(client write key)、服务器写入密钥(server write key)应该就是指的这里的写密钥(write key)。
可导出的加密算法从random消息中导出它们的初始化向量(IV):
client_write_IV = MD5(ClientHello.random + ServerHello.random);
server_write_IV = MD5(ServerHello.random + ClientHello.random);
MD5输出通过丢弃最少的有用字节来修剪至一个合适的大小。
6.2.2.1 导出密钥生成例子
7 安全考虑
8 引用
1、 The Secure Sockets Layer (SSL) Protocol Version 3.0, http://www.rfc-base.org/rfc-6101.html
2、 The Secure Sockets Layer (SSL) Protocol Version 3.0, http://www.rfc-base.org/txt/rfc-6101.txt
3、 The TLS Protocol Version 1.0, http://www.ietf.org/rfc/rfc2246.txt
4、 The Secure Sockets Layer (SSL) Protocol Version 3.0, https://www.rfc-editor.org/rfc/rfc6101.txt
5、 Asymmetric-Key Cryptography, http://www.cs.cornell.edu/courses/CS5430/2013sp/TL04.asymmetric.html
发表评论
-
SMTP
2021-05-22 02:50 348写道 https://lobin.iteye.com/a ... -
SMTP
2021-05-22 02:48 0SMTP 是一个简单的邮 ... -
GnuTLS
2020-10-20 06:44 1037GnuTLS nettle # wget ftp:// ... -
网络协议 第3篇: IP v6
2020-10-14 04:50 382>which ipv6 /cygdrive/c/W ... -
网络协议 第2篇: IP
2020-01-12 19:52 517IP IPv4网络地址是一个32位的地址。 可以 ... -
对象文件结构的分析:VC
2019-06-01 02:03 623我们在Windows下编程时,如我们在VC下开发C/C++ ... -
Windows可执行文件结构的分析:exe 第3篇:VC
2019-06-01 00:23 17216Windows下程序通常是以.exe后缀的程序文件,这是一 ... -
HTTP规范中关于消息的header头部
2019-03-22 21:06 1829HTTP规范中关于消息的header头部 HTTP ... -
HTTP规范中关于请求/响应中的message-body和entity-body
2019-03-10 01:37 3118HTTP规范中关于请求/响应中的message-bo ... -
Windows可执行文件结构的分析:exe 第2篇
2019-03-02 22:05 13487以下是在Windows Cygwin环境下gcc编译的可执 ... -
HTTP协议分析
2019-02-27 17:40 2625写道 Hypertext Transfer Protoc ... -
数字签名算法:DSA
2019-01-18 23:09 929DSA private static Priva ... -
非对称加密算法
2019-01-18 02:37 1802非对称加密算法:ECIESwithAES 参考椭圆 ... -
elasticsearch
2017-12-28 20:30 716相似度 相似度算法 余弦相似度算法 余弦 ... -
dubbo 协议
2017-12-06 16:32 2346encode one to one org.jboss.net ... -
Thrift
2017-10-28 05:42 590<版本号,2字节><无用字段,1字节> ... -
RSA
2017-06-06 02:55 807公钥长度读写 读取长度: this.le ... -
Code39中的校验和(Check Sum)实现
2017-05-29 04:42 2201private int getCharIndex(c ... -
随便写的一段代码
2017-05-28 04:12 1832public enum HandshakeType { ... -
OpenSSL
2017-05-24 23:31 818写道 GnuTLShttps://www.iteye.c ...
相关推荐
BoringSSL是一个由Google维护的SSL/TLS实现,它是OpenSSL的一个分支,旨在提供更简洁的代码库,更严格的审核,以及对现代硬件优化的支持。这个win-x86_64包显然为Windows 64位平台设计,包含了三个关键组件:`bssl....
在IT行业中,尤其是在Web服务器和应用服务器领域,SSL(Secure Sockets Layer)和其后续版本TLS(Transport Layer Security)是确保数据传输安全的关键技术。Tomcat作为一款流行的Java应用服务器,支持SSL配置以实现...
MySQL 使用SSL连接配置详解 在现代数据库管理中,安全性是至关重要的,SSL(Secure Sockets Layer)连接为MySQL提供了一种加密数据传输的方式,确保了客户端和服务器之间的通信不被窃听或篡改。本文将详细介绍如何...
在Kubernetes(K8S)集群环境中,安全套接字层(SSL)证书的监控是确保服务安全和稳定的重要环节。SSL证书用于加密网络通信,确保数据传输的安全性。`ssl-exporter`是一款专为监控SSL/TLS证书状态设计的Prometheus ...
在Python编程过程中,有时会遇到导入模块时遇到错误,例如"ImportError: No module named _ssl"。这个错误通常表示Python无法找到SSL模块,该模块是Python标准库的一部分,用于处理安全套接层(SSL)和传输层安全...
**Apache SSL 插件:mod_ssl** Apache HTTP Server 是世界上最流行的Web服务器软件,而mod_ssl是Apache的一个核心模块,专门用于实现安全套接层(SSL)协议,为网站提供安全的HTTPS服务。SSL(Secure Sockets Layer...
SSL/TLS(安全套接层/传输层安全)协议是互联网上广泛使用的安全通信协议,用于在客户端(如浏览器)和服务器之间建立安全、私密的连接,保护数据免受窃听和篡改。RFC5246文档是SSL/TLS协议的最新版本,正式名为...
SSL(Secure Sockets Layer)证书是互联网安全领域的重要组成部分,用于加密用户与服务器之间的通信,确保数据在传输过程中不被窃取或篡改。在本地生成SSL证书,可以帮助开发者在测试环境中模拟真实环境的安全设置,...
### 信安SSL配置知识点详解 #### 一、实施步骤和操作过程 1. **登录管理界面**: - **管理口**: 设备的Port1口,地址为192.168.1.99。 - **登录方式**: - 直接连接笔记本电脑至设备的Port1口并通过浏览器访问`...
### STM32 实现SSL通讯 #### 一、引言 随着网络安全日益受到重视,确保数据传输的安全性成为了一个不容忽视的问题。对于嵌入式系统而言,如何在资源受限的条件下实现安全通信变得尤为重要。本篇文章将基于STM32F...
### ApacheFtpServer之ssl配置详解 #### 一、FTPS概述 FTPS(File Transfer Protocol Secure),即安全文件传输协议,是一种通过SSL/TLS(Secure Sockets Layer/Transport Layer Security)来保护传统FTP(File ...
本文将详细介绍如何在Nginx服务器上配置SSL自签名证书。 首先,我们需要生成自签名SSL证书。这通常包括以下步骤: 1. **生成RSA密钥**:使用`openssl genrsa`命令创建一个带有密码保护的RSA私钥。例如,`openssl ...
ssl_session_cache shared:SSL:10m; # 管理 SSL 会话缓存 ssl_session_timeout 10m; # 设置 SSL 会话超时时间 ``` 6. **处理静态资源**: - 通过 `location` 块配置,Nginx 可以高效地处理各种静态文件请求,...
在本文中,我们将深入探讨如何使用Visual C++(VC)进行SSL通信,主要基于OpenSSL库来实现Socket服务器和客户端的交互。SSL(Secure Sockets Layer)是一种安全协议,用于在互联网上提供加密通信和身份验证,而...
本报告就如何配置SSL/TLS以提供最先进的身份验证和加密技术提出了一般性建议。ssl引擎提供的选项是从 自从Netscape开发SSL2.0以来的早期。TLS的引入使问题变得更具有挑战性,因为服务器和客户端根据各个ssl引擎提供...
SSL证书在线生成系统源码是实现网站安全的重要工具,它基于公钥基础设施(PKI)原理,用于在互联网上建立安全的数据传输通道。本系统允许用户通过在线方式申请并生成SSL证书,简化了传统SSL证书获取流程,提升了用户...
### 超微H12SSL-C用户手册关键知识点解析 #### 一、产品概述与文档准确性声明 根据所提供的文件信息,“超微H12SSL-C用户手册”是一份关于超微H12SSL-C系列服务器主板(包括H12SSL-i/C/CT/NT型号)的操作指南。该...
在Linux环境下,使用C语言编写基于SSL(Secure Socket Layer)的TCP程序是一项常见的任务,尤其在开发安全通信软件时。SSL是一种网络安全协议,用于在Internet上提供加密通信和身份验证。下面将详细介绍如何在Linux...
SSL(Secure Socket Layer)是一种广泛使用的网络安全协议,其主要任务是提供加密通信和身份认证,确保数据在网络传输过程中的安全性和完整性。SSL的工作原理涉及到多个关键概念和技术。 首先,SSL的核心在于加密,...
在Android平台上,SSL(Secure Sockets Layer)证书验证是一个关键的安全环节,用于保护应用程序与服务器之间的通信不被窃听或篡改。SSL证书是身份验证的一种方式,它确保了用户与服务器之间的连接是安全的,数据...