关于im:TLS协议分析-五-handshake协议-证书与密钥交换

3次阅读

共计 12852 个字符,预计需要花费 33 分钟才能阅读完成。

5.4. handshake — Server Certificate

当服务器确定了 CipherSuite 后,依据 CipherSuite 外面的认证算法,如果须要发送证书给客户端,那么就发送 Server Certificate 音讯给客户端。Server Certificate 总是在 ServerHello 之后立刻发送,所以在同一个 RTT 里。

Server Certificate 外面蕴含了服务器的证书链。

音讯构造:

opaque ASN.1Cert<1..2^24-1>;struct {ASN.1Cert certificate_list<0..2^24-1>;} Certificate;

certificate_list
: 证书列表,发送者的证书必须是第一个,后续的每一个证书都必须是前一个的签订证书。根证书能够省略

证书申请的时候,个别会收到好几个证书,有的须要本人依照这个格局来拼接成证书链。

如果服务器要认证客户端的身份,那么服务器会发送 Certificate Request 音讯,客户端应该也以 这条 Server Certificate 音讯的格局回复。

服务器发送的证书必须:

  • 证书类型必须是 X.509v3。除非明确地协商成别的了(比拟少见,rfc 里提到了例如 [OpenPGP 格局] 链接 https://tools.ietf.org/html/r… )。
  • 服务器证书的公钥,必须和抉择的密钥替换算法配套。
密钥替换 + 认证算法 配套的证书中公钥类型
RSA / RSA_PSK RSA 公钥;证书中必须容许私钥用于加密(即如果应用了 X509V3 规定的 key usage 扩大,keyEncipherment 比特位必须置位)这种用法没有前向安全性,因而在 TLS 1.3 中被废除了
DHE_RSA / ECDHE_RSA RSA 公钥;证书中必须容许私钥用于签名 (即如果应用了 X509V3 规定的 key usage 扩大,digitalSignature 比特位必须置位),并且容许 server key exchange 音讯将要应用的签名模式(例如 PKCS1_V1.5,OAEP 等) 和 hash 算法(例如 sha1, sha256 等)
DHE_DSS DSA 公钥; 历史遗留产物,素来没有被大规模用过,安全性差,废除状态。证书必须容许私钥用于签名,必须容许 server key exchange 音讯中应用的 hash 算法。
DH_DSS / DH_RSA Diffie-Hellman 公钥; 要求 key usage 外面的 keyAgreement 比特位必须置位。这种用法没有前向安全性,因而在 TLS 1.3 中被废除了
ECDH_ECDSA / ECDH_RSA 能做 ECDH 用处的公钥;公钥必须应用 客户端反对的 ec 曲线和点格局。这种用法没有前向安全性,因而在 TLS 1.3 中被废除了
ECDHE_ECDSA ECDSA 用处的公钥;证书必须运输私钥用作签名,必须容许 server key exchange 音讯外面要用到的 hash 算法。公钥必须应用客户端反对的 ec 曲线和点格局。
  • “server_name”和“trusted_ca_keys”扩大用于疏导证书抉择。

其中有 5 种是 ECC 密钥替换算法:ECDH_ECDSA, ECDHE_ECDSA, ECDH_RSA, ECDHE_RSA, ECDH_anon。
ECC(椭圆曲线)体制相比 RSA,因为公钥更小,性能更高,所以在挪动互联网环境下越发重要。
以上 ECC 的 5 种算法都用 ECDH 来计算 premaster secret,仅仅是 ECDH 密钥的生命周期和认证算法不同。
其中只有 ECDHE_ECDSA 和 ECDHE_RSA 是前向平安的。

如果客户端在 ClientHello 里提供了“signature_algorithms”扩大,那么服务器提供的所有证书必须用“signature_algoritms”中提供的 hash/signature 算法对 之一签订。要留神的是,这意味着,一个蕴含某种签名算法密钥的证书,可能被另一种签名算法签订(例如,一个 RSA 公钥可能被一个 ECDSA 公钥签订)。(这在 TLS1.2 和 TLS1.1 中是不一样的,TLS1.1 要求所有的算法都雷同。)留神这也意味着 DH_DSS,DH_RSA,ECDH_ECDSA, 和 ECDH_RSA 密钥替换不限度签订证书的算法。固定 DH 证书可能应用”signature_algorithms”扩大列表中的 hash/ 签名算法对 中的某一个签订。名字 DH_DSS, DH_RSA, ECDH_ECDSA, 和 ECDH_RSA 只是历史起因,这几个名字的后半局部中指定的算法,并不会被应用,即 DH_DSS 中的 DSS 并不会被应用,DH_RSA 中并不会应用 RSA 做签名,ECDH_ECDSA 并不会应用 ECDSA 算法。。。
如果服务器有多个证书,就必须从中抉择一个,个别依据服务器的外网 ip 地址,SNI 中指定的 hostname,服务器配置来做抉择。如果服务器只有一个证书,那么要确保这一个证书合乎这些条件。
要留神的是,存在一些证书应用了 TLS 目前不反对的 算法组合。例如,应用 RSASSA-PSS 签名公钥的证书(即证书的 SubjectPublicKeyInfo 字段是 id-RSASSA-PSS)。因为 TLS 没有给这些算法定义对应的签名算法,这些证书不能在 TLS 中应用。
如果一个 CipherSuite 指定了新的 TLS 密钥替换算法,也会指定证书格局和要求的密钥编码方法。

5.5. handshake — Server Key Exchange

服务器会在 server Certificate 音讯之后,立刻发送 Server Key Exchange 音讯。
(如果协商出的 CipherSuite 不须要做认证,即 anonymous negotiation,会在 ServerHello 之后立刻发送 Server Key Exchange 音讯)

只有在 server Certificate 音讯没有足够的信息,不能让客户端实现 premaster 的密钥替换时,服务器才发送 server Key Exchange,次要是对前向平安的几种密钥协商算法,列表如下:

  1. DHE_DSS
  2. DHE_RSA
  3. DH_anon
  4. ECDHE_ECDSA
  5. ECDHE_RSA
  6. ECDH_anon

对上面几种密钥替换办法,发送 ServerKeyExchange 音讯是非法的:

  1. RSA
  2. DH_DSS
  3. DH_RSA
  4. ECDH_ECDSA
  5. ECDH_RSA

须要留神的是,ECDH 和 ECDSA 公钥的数据结构是一样的。所以,CA 在签订一个证书的时候,可能要应用 X.509 v3 的 keyUsage 和 extendedKeyUsage 扩大来限定 ECC 公钥的应用形式。

ServerKeyExchange 传递足够的信息给客户端,来让客户端替换 premaster secret。个别要传递的是:一个 Diffie-Hellman 公钥,或者一个其余算法 (例如 RSA) 的公钥。

在 TLS 理论部署中,咱们个别只应用这 4 种:ECDHE_RSA, DHE_RSA, ECDHE_ECDSA,RSA

其中 RSA 密钥协商(也能够叫密钥传输)算法,因为没有前向安全性,在 TLS 1.3 外面曾经被破除了。参见:[Confirming Consensus on removing RSA key Transport from TLS 1.3] 链接 http://www.ietf.org/mail-arch…

音讯格局:

enum {dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa,    ec_diffie_hellman} KeyExchangeAlgorithm;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 */dh_p
   Diffie-Hellman 密钥协商计算的大质数模数。dh_g
   Diffie-Hellman 的生成元,dh_Ys
   服务器的 Diffie-Hellman 公钥 (g^X mod p).  struct {opaque point <1..2^8-1>;} ECPoint;  enum {explicit_prime (1), explicit_char2 (2),
         named_curve (3), reserved(248..255) } ECCurveType;  struct {
      ECCurveType    curve_type;
      select (curve_type) {          case named_curve:
              NamedCurve namedcurve;
      };
  } ECParameters;            struct {
      ECParameters    curve_params;
      ECPoint         public; //ECDH 的公钥
  } ServerECDHParams;struct {select (KeyExchangeAlgorithm) {        case dh_anon:
            ServerDHParams params;        case dhe_dss:        case dhe_rsa:
            ServerDHParams params;
            digitally-signed struct {opaque client_random[32];
                opaque server_random[32];
                ServerDHParams params;
            } signed_params;        case ec_diffie_hellman:
            ServerECDHParams    params;
            Signature           signed_params;        case rsa:        case dh_dss:        case dh_rsa:              struct {} ;        /* message is omitted for rsa, dh_dss, and dh_rsa */
        /* may be extended, e.g., for ECDH -- see [TLSECC] */
    };
} ServerKeyExchange;

params
   服务器的密钥替换参数。signed_params
   对须要认证的(即非 anonymous 的)密钥替换,对服务器的密钥替换参数的数字签名。

ECParameters 构造比拟麻烦,其中 ECCurveType 是反对 3 种曲线类型的,能够自行指定椭圆曲线的多项式系数,基点等参数。然而,咱们根本不会用到这种性能,因为个别部署都是应用 NamedCurve,即参数曾经事后选定,各种密码学库广泛都反对的一组曲线,其中目前用的最广的是 secp256r1(还被称为 P256,或 prime256v1)

NamedCurve 列表中比拟重要的曲线(在 TLS1.3 中,只保留了这几条曲线。),定义如下:

enum {
    ...
    secp256r1 (23), secp384r1 (24), secp521r1 (25),
    reserved (0xFE00..0xFEFF),
    (0xFFFF)
} NamedCurve;

ECDHE_RSA 密钥替换算法的 SignatureAlgorithm 是 rsa。
ECDHE_RSA 密钥替换算法的 SignatureAlgorithm 是 ecdsa。

如果客户端提供了“signature_algorithms”扩大,则签名算法和 hash 算法必须是列在扩大中的算法。
要留神的是,这个中央可能有不统一,例如客户端可能提供了 DHE_DSS 密钥替换,然而“signature_algorithms”扩大中没有 DSA 算法,在这类状况下,为了正确地协商,服务器必须确保满足本人抉择的 CipherSuite 满足“signature_algorithms”的限度。这不优雅,然而是为了把对原来的 CipherSuite 协商的设计的改变减到最小,而做的斗争。

并且,hash 和签名算法,必须和服务器的证书外面的公钥兼容。

5.6. handshake — Certificate Request

TLS 规定了一个可选性能:服务器能够认证客户端的身份,这通过服务器要求客户端发送一个证书实现,服务器应该在 ServerKeyExchange 之后立刻发送 CertificateRequest 音讯。

音讯构造:

enum {rsa_sign(1), dss_sign(2), rsa_fixed_dh(3),dss_fixed_dh(4),
    rsa_ephemeral_dh_RESERVED(5),dss_ephemeral_dh_RESERVED(6),
    fortezza_dms_RESERVED(20),
    ecdsa_sign(64), rsa_fixed_ecdh(65),
    ecdsa_fixed_ecdh(66), 
    (255)
} ClientCertificateType;

opaque DistinguishedName<1..2^16-1>;struct {
    ClientCertificateType certificate_types<1..2^8-1>;
    SignatureAndHashAlgorithm
      supported_signature_algorithms<2^16-1>;
    DistinguishedName certificate_authorities<0..2^16-1>;
} CertificateRequest;

certificate_types
: 客户端能够提供的证书类型。

  • rsa_sign 蕴含 RSA 公钥的证书。
  • dss_sign 蕴含 DSA 公钥的证书。
  • rsa_fixed_dh 蕴含动态 DH 公钥的证书。
  • dss_fixed_dh 蕴含动态 DH 公钥的证书。

    supported_signature_algorithms
    : 服务器反对的 hash/signature 算法的列表。

    certificate_authorities
    : 服务器能够承受的 CA(certificate_authorities)的 distinguished names 的列表 DER 编码格局.

这些 distinguished names 可能为 root CA 或者次级 CA 指定了想要的 distinguished name,因而,这个音讯能够用来形容已知的 root,或者心愿的受权空间。
如果 certificate_authorities 列表是空的,那么客户端能够发送任何适当的 ClientCertificateType 类型的证书,如果没有别的限度的话。

certificate_types 和 supported_signature_algorithms 字段的穿插抉择很简单。certificate_types 这个字段从 SSLv3 时代就定义了,然而始终都没有具体定义,其大多数性能都被 supported_signature_algorithms 代替了。
有如下规定:

  • 客户端提供的任何证书,必须用一个 supported_signature_algorithms 中呈现过的 hash/signature 算法对 签名.
  • 客户端提供的末端证书必须提供一个和 certificate_types 兼容的 key。如果这个 key 是一个签名 key,那必须能和 supported_signature_algorithms 中提供的某个 hash/signature 算法对配合应用。
  • 因为历史起因,某些客户端证书类型的名字,蕴含了证书的签名算法,例如,晚期版本的 TLS 中,rsa_fixed_dh 意思是一个被 RSA 算法签订,并且蕴含一个固定 DH 密钥的证书。在 TLS1.2 中,这个性能被 supported_signature_algorithms 淘汰,并且证书类型不再限度用来签订证书的算法。例如,如果服务器发送了 dss_fixed_dh 证书类型,和 {{sha1, dsa}, {sha1,rsa} } 签名类型,客户端能够回复一个 蕴含动态 DH 密钥,用 RSA-sha1 签订的证书。
  • 如果协商进去的是匿名 CipherSuite,服务器不能要求客户端认证。

5.7. handshake — Server Hello Done

在 ServerHello 和相干音讯曾经解决完结后,服务器发送 ServerHelloDone。在发送 ServerHelloDone 后,服务器开始期待客户端的响应。

ServerHelloDone 音讯示意,服务器曾经发送完了密钥协商须要的音讯,并且客户端能够开始客户端的密钥协商解决了。

收到 ServerHelloDone 后,客户端应该确认服务器提供了非法的证书,并且确认服务器的 ServerHello 音讯外面的参数是能够承受的。

音讯格局:

  struct {} ServerHelloDone;

5.8. handshake — Client Certificate

ClientCertificate 音讯是客户端收到 ServerHelloDone 后,能够发送的第一条音讯。仅当服务器要求了一个证书的状况下,客户端才发送 ClientCertificate 音讯,如果没有可用的适合证书,客户端必须发送一条不蕴含任何证书的 ClientCertificate 音讯(即 certificate_list 构造长度为 0)。

如果客户端没有发送任何证书,服务器自行决定,能够放弃要求客户端认证,持续握手;或者发送一条 fatal handshake_failure 的 alert 音讯,断开连接。并且,如果证书链的某些方面是不能承受的(比方证书没有被可信赖的 CA 签订),服务器能够自行决定,是持续握手(放弃要求客户端认证),或者发送一条 fatal 的 alert。

客户端证书应用和 ServerCertificate 雷同的构造发送。

ClientCertificate 把客户端的证书链发送给服务器。服务器会应用证书链来验证 CertificateVerify 音讯(如果应用基于签名的客户端认证),或者来计算 premaster secret(对于非短暂的 DH)。证书必须和协商进去的 CipherSuite 的密钥替换算法配套,并和任何协商的扩大配套。

尤其是:

  • 证书必须是 X.509v3 类型的。
  • 客户端的末级证书的公钥必须和 CertificateRequest 里列出的证书类型兼容。
客户端证书类型 证书公钥类型
rsa_sign RSA 公钥;证书必须容许公钥用于 certificateVerify 音讯中的数字签名和 hash 算法
dss_sign DSA 公钥;证书必须容许密钥应用 CertificateVerify 中的 hahs 函数做签名;
ecdsa_sign 能够用作 ECDSA 的公钥;证书必须容许 公钥用 CertificateVerify 中的 hash 函数做签名;公钥必须应用服务器反对的曲线,和点格局;
rsa_fixed_dh / dss_fixed_dh Diffie-Hellman 公钥; 必须应用和服务器 key 雷同的参数。
rsa_fixed_ecdh / ecdsa_fixed_ecdh 能够用作 ECDH 的公钥。必须和服务器的公钥应用同样的曲线,同样的点格局
  • 如果 certificate_authorities 列表不是空的,客户端证书链中的某一个证书必须是 CA 中的某一个签订的。
  • 证书必须应用 服务器能够承受的 hash/signature 算法对。

相似于 Server Certificate,有一些证书目前无奈在 TLS 中应用。

5.9. handshake — Client Key Exchange

客户端必须在客户端的 Certificate 音讯之后,立刻发送 ClientKeyExchange 音讯。
或者必须在 ServerHelloDone 后立刻发送 ClientKeyExchange 音讯。

ClientKeyExchange 音讯中,会设置 premaster secret,通过发送 RSA 公钥加密 premaster secret 的密文,或者发送容许单方得出雷同的 premaster secret 的 Diffie-Hellman 参数。

当客户端应用短暂的 Diffie-Hellman 密钥对时,ClientKeyExchange 蕴含客户端的 Diffie-Hellman 公钥。如果客户端发送一个蕴含动态 Diffie-Hellman 指数的证书(比方,在应用固定 DH 的客户端认证),那么这条音讯必须被发送,并且必须为空。

音讯构造:
音讯的抉择取决于抉择的密钥替换算法。

struct {select (KeyExchangeAlgorithm) {        case rsa:
            EncryptedPreMasterSecret;        case dhe_dss:        case dhe_rsa:        case dh_dss:        case dh_rsa:        case dh_anon:
            ClientDiffieHellmanPublic;        case ec_diffie_hellman: 
            ClientECDiffieHellmanPublic;
    } exchange_keys;
} ClientKeyExchange;

5.9.(1). RSA 加密的 Premaster Secret 音讯

如果用 RSA 做密钥协商和认证,客户端生成 48 字节的 premaster secret,应用服务器证书外面的公钥加密,而后把密文 EncryptedPreMasterSecret 发送给服务器,构造定义如下:

struct {
    ProtocolVersion client_version;
    opaque random[46];
} PreMasterSecret;

client_version
   客户端反对的最新协定版本号,这个字段用来检测中间人版本回退攻打。T
random   46 字节的,平安生成的随机值。struct {public-key-encrypted PreMasterSecret pre_master_secret;} EncryptedPreMasterSecret;

pre_master_secret
   这个随机值由客户端生成,用于生成 master secret。

注:PreMasterSecret 外面的 client_version 是 ClientHello.client_version,而不是协商的到的版本号,这个个性用来阻止版本回退攻打。可怜的是,有些不正确的老的代码应用了协商失去的版本号,导致查看 client_version 字段的时候,和正确的实现无奈互通。

客户端实现必须在 PreMasterSecret 中发送正确的版本号。如果 ClientHello.client_version 的版本号是 TLS 1.1 或者更高,服务器实现必须如下查看版本号。如果版本号是 TLS 1.0 或者更早,服务器必须查看版本号,然而能够通过配置项敞开查看。

要留神的是,如果版本号查看失败了,PreMasterSecret 应该像上面形容的那样填充成随机数。

TLS 中的 RSA 应用的是 PKCS1-V1.5 填充(PKCS1-V1.5 也是 openssl 库 RSA 的默认填充形式)。Bleichenbacher 在 1998 年发表了一种针对 PKCS1-V1.5 的抉择密文攻打,Klima 在 2003 年发现 PKCS1-V1.5 中 PreMasterSecret 版本号查看的一个侧通道攻打。只有 TLS 服务器裸露一条特定的音讯是否合乎 PKCS1-V1.5 格局,或裸露 PreMasterSecret 解密后构造是否非法,或版本号是否非法,就能够用下面 2 种办法攻打。

Klima 还提出了完全避免这类攻打的办法:对格局不正确的音讯,版本号不符的状况,要做出和完全正确的 RSA 块一样的响应,要让客户端辨别不出这 3 种状况。
具体地说,要如下:

  1. 生成 46 字节的密码学平安随机值 R
  2. 解密音讯,取得明文 M
  3. 如果 PKCS#1 填充不正确,或者 PreMasterSecret 音讯的长度不是 48 字节,则
    pre_master_secret = ClientHello.client_version || R
    或者如果 ClientHello.client_version <= TLS 1.0,并且明确禁止了版本号查看,则
    pre_master_secret = ClientHello.client_version || M[2..47]

留神:明确地用 ClientHello.client_version 结构 pre_master_secret 时,当客户端在原来的 pre_master_secret 中发送了谬误的 客户端版本值时,会产生一个不非法的 master_secret。

另一种解决问题的办法是,把版本号不符,当成 PKCS-1 格局谬误来看待,并且齐全随机填充 premaster secret。

  1. 生成 48 字节的密码学平安随机值 R
  2. 解密 PreMasterSecret 复原出明文 M
  3. 如果 PKCS#1 填充不正确,或者音讯的长度不是 48 字节,则
    pre_master_secret = R
    或者如果 ClientHello.client_version <= TLS 1.0,并且 明确禁止了版本号查看,则
    pre_master_secret = M
    或者如果 M[0..1] != CleintHello.client_version
    pre_master_secret = R
    或者
    pre_master_secret = M

只管实际中,还没有发现针对这种构造的攻打,Klima 在论文中形容了几种实践上的攻击方式,因而举荐上述的第一种构造。

在任何状况下,一个 TLS 服务器相对不能在:1. 解决 RSA 加密的 premaster 音讯失败, 2. 或者版本号查看失败 时产生 alert 音讯。当遇到这两种状况时,服务器必须用随机生成的 premaster 值持续握手。服务器能够把造成失败的实在起因 log 下来,用于考察问题,然而必须小心确保不能把这种信息透露给攻击者(比方通过工夫侧通道,log 文件,或者其它通道等透露)。

RSAES-OAEP 加密体制,更能抵制 Bleichenbacher 发表的攻打,然而,为了和晚期的 TLS 版本最大水平放弃兼容,TLS 依然规定应用 RSAES-PKCS1-v1_5 体制。只有恪守了下面列出的倡议,目前还没有 Bleichenbacher 的变动模式能攻破 TLS。

实现的时候要留神:公钥加密的数据用 字节数组 <0..2^16-1> 的模式示意。因而,ClientKeyExchange 中的 RSA 加密的 PreMasterSecret 后面有 2 个字节用来示意长度。这 2 个字节在应用 RSA 做密钥协商时,是冗余的,因为此时 EncryptedPreMasterSecret 是 ClientKeyExchange 中的惟一字段,因而能够无歧义地得出 EncryptedPreMasterSecret 的长度。因而更早的 SSLv3 标准没有明确规定 public-key-encrypted 数据的编码格局,因而有一些 SSLv3 的实现没有蕴含 长度字段,这些实现间接把 RSA 加密的数据放入了 ClientKeyExchange 音讯外面。
TLS 标准要求 EncryptedPreMasterSecret 字段蕴含长度字段。因而得出的后果会和一些 SSLv3 的实现不兼容。实现者从 SSLv3 降级到 TLS 时,必须批改本人的实现,以承受并且生成带长度的格局。如果一个实现要同时兼容 SSLv3 和 TLS,那就应该依据协定版本确定本人的行为。

留神:依据 Boneh 等在 2003 年 USENIX Security Symposium 上发表的论文“Remote timing attacks are practical”,针对 TLS RSA 密钥替换的近程工夫侧通道攻打,是 理论可行的,起码当客户端和服务器在同一个 LAN 里时是可行的。因而,应用动态 RSA 密钥的实现,必须应用 RSA blinding,或者 Boneh 论文中提到的,其余抵制工夫侧通道攻打的技术。

openssl 中的 RSA blinding,参见:http://linux.die.net/man/3/rs…

5.9.(2). 客户端 Diffie-Hellman 公钥

这条音讯把客户端的 Diffie-Hellman 公钥 (Yc) 发送给服务器。

Yc 的编码方式由 PublicValueEncoding 决定。

音讯的构造:

enum {implicit, explicit} PublicValueEncoding;

implicit
   如果客户端曾经发送了一个蕴含适合的 DH 公钥的证书(即 fixed_dh 客户端认证形式),那么 Yc 曾经隐式蕴含了,不须要再发送。这种状况下,ClientKeyExchange 音讯必须发送,并且必须是空的。explicit
   示意 Yc 须要发送。struct {select (PublicValueEncoding) {case implicit:           struct {};         case explicit:            opaque dh_Yc<1..2^16-1>;
    } dh_public;
} ClientDiffieHellmanPublic;

dh_Yc
   客户端的 Diffie-Hellman 公钥 Yc.

5.9.(3). 客户端 EC Diffie-Hellman 公钥

struct {select (PublicValueEncoding) {case implicit:          struct {};       case explicit:           ECPoint ecdh_Yc;
    } ecdh_public;
} ClientECDiffieHellmanPublic;

Diffie-Hellman 推广到椭圆曲线群上,就是 EC Diffie-Hellman,简称 ECDH,其它的计算,和个别的 DH 计算相似。

ECDH 是目前最重要的密钥协商算法 http://vincent.bernat.im/en/b…

5.10. handshake — Cerificate Verify

当须要做客户端认证时,客户端发送 CertificateVerify 音讯,来证实本人的确领有客户端证书的私钥。这条音讯仅仅在客户端证书有签名能力的状况下发送(就是说,除了含有固定 Diffie-Hellman 参数的证书以外的证书)。CertificateVerify 必须紧跟在 ClientKeyExchange 之后发送。

音讯构造:
Structure of this message:

struct {
     digitally-signed struct {opaque handshake_messages[handshake_messages_length];
     }
} CertificateVerify;

此处,handshake_messages 示意所有发送或者接管的握手音讯,从 client hello 开始,始终到 CertificateVerify 之前的所有音讯,包含 handshake 音讯的 type 和 length 字段,这是之前所有握手构造体的拼接。要留神,这要求单方在握手过程中,都得缓存所有音讯,或者在握手过程中,用每一种可能的 hash 算法计算到 CeritificateVerify 为止的 hash 值。

signature 中用的 hash 和签名算法必须是 CertificateRequest 的 supported_signature_algorithms 中的某一种。另外,hash 和签名算法必须和客户端的证书的算法兼容。
RSA 公钥可能被用于任何容许的 hash 函数,只有遵循证书中的限度。

本文转自微信后盾团队, 如有进犯, 请分割咱们立刻删除

OpenIMgithub 开源地址:

https://github.com/OpenIMSDK/…

OpenIM 官网: https://www.rentsoft.cn

OpenIM 官方论坛: https://forum.rentsoft.cn/

更多技术文章:

开源 OpenIM:高性能、可伸缩、易扩大的即时通讯架构
https://forum.rentsoft.cn/thr…

【OpenIM 原创】简略轻松入门 一文解说 WebRTC 实现 1 对 1 音视频通信原理
https://forum.rentsoft.cn/thr…

【OpenIM 原创】开源 OpenIM:轻量、高效、实时、牢靠、低成本的音讯模型
https://forum.rentsoft.cn/thr…

正文完
 0