TLS/DTLS 使用 Raw Public Key

本文介绍一下如何在 TLS/DTLS 中使用 Raw Public Key 替代传统的 X.509 Certificate.


简介


通常情况下, TLS 握手过程中使用 PKIX certificate, 通过校验这些证书是否合法来确保 TLS 通信的安全。

但是,在一些比较小的场景中,服务器客户端都使用自签名的证书,然后这些证书通过其他方式分发给需要通信的各个节点。在这种情况下,证书校验就退化为仅仅比较证书的二进制内容是否相等了,其他的校验都将不再需要。

因此, TLS 提供了一种机制,可以使用 X.509 证书中的一部分内容来表示这整个证书,以便获得以下好处:

  1. TLS 握手过程中交换的证书信息将会很小,减少握手过程所需要交换的数据量
  2. 处理证书的代码将会很简单。通常的 TLS 实现中,处理证书将会是很大一个的功能模块。
  3. 仅需要实现很少的 ASN.1 解析器功能。
  4. 证书校验模块也将被大幅度简化。

注意, 这些优点对于物联网/嵌入式设备将会是非常重要的。


RawPublicKey VS X.509Certificate


一个完整的 X.509 Certificate 将会携带如下信息:

  1. Certificate Version (V3)
  2. Serverial Number
  3. Siganture Algorithm, Signature
  4. Issuer
  5. Subject
  6. Validate From, Validate To
  7. Public Key
  8. Other extenstions(SubjectAltName, Key Usage, Extended Key usage, OCSP, CRL and so on)

对于一个 RawPublicKey, 它携带如下信息:

  1. Public Key

就像下图这么简单:

在这里插入图片描述

编码这些信息仅仅需要 91 字节。

而通常的证书的字节大小在 K 的数量级上。

RawPublicKey 的内容是 X.509 Certificate 的 SubjectPublicKeyInfo 字段。如下:

Certificate  ::=  SEQUENCE  {
        tbsCertificate       TBSCertificate,
        signatureAlgorithm   AlgorithmIdentifier,
        signatureValue       BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
        version         [0]  EXPLICIT Version DEFAULT v1,
        serialNumber         CertificateSerialNumber,
        signature            AlgorithmIdentifier,
        issuer               Name,
        validity             Validity,
        subject              Name,
        subjectPublicKeyInfo SubjectPublicKeyInfo,
        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                             -- If present, version MUST be v2 or v3
        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                             -- If present, version MUST be v2 or v3
        extensions      [3]  EXPLICIT Extensions OPTIONAL
                             -- If present, version MUST be v3
        }

新扩展: client_certificate_type && server_certificate_type


在 TLS 握手过程中, 这两个扩展均可携带在 ClientHelloServerHello 中。

它的值表示客户端或服务器支持的 TLS Certificate 类型(可以是多种类型)。常见的 TLS certificate 类型有: X.509 和 RawPublicKey.

opaque ASN.1Cert<1..2^24-1>;

struct {
	select(certificate_type){
		// certificate type defined in this document.
		case RawPublicKey:
			opaque ASN.1_subjectPublicKeyInfo<1..2^24-1>;
		// X.509 certificate defined in RFC 5246
		case X.509:
			ASN.1Cert certificate_list<0..2^24-1>;
		// Additional certificate type based on
		// "TLS Certificate Types" subregistry
	};
} Certificate;

struct {
	select(ClientOrServerExtension) {
		case client:
			CertificateType client_certificate_types<1..2^8-1>;
		case server:
			CertificateType client_certificate_type;
	}
} ClientCertTypeExtension;

struct {
	select(ClientOrServerExtension) {
		case client:
			CertificateType server_certificate_types<1..2^8-1>;
		case server:
			CertificateType server_certificate_type;
	}
} ServerCertTypeExtension;

TLS 握手过程


握手流程大体如下:

client_hello,
client_certificate_type,
server_certificate_type ->
                                     <- server_hello,
                                         client_certificate_type,
                                         server_certificate_type,
                                         certificate,
                                         server_key_exchange,
                                         certificate_request,
                                         server_hello_done
certificate,
client_key_exchange,
certificate_verify,
change_cipher_spec,
finished ->
                                    <- change_cipher_spec,
                                        finished

Application Data        <------->  Application Data

影响到的 TLS 握手消息包括:

  1. ClientHello
  2. ServerHello
  3. Certificate

ClientHello 信息


为了表明自己支持 RawPublicKey 模式, 客户端需要在 ClientHello消息中附带 client_certificate typeserver_certificate type 扩展。

ClientHello.client_certificate_type 表示客户端支持的 TLS certificate type. 当服务器要求客户端发送自己的证书的时候, 客户端需要发送对应格式的证书给服务器端。

如果客户端不支持除了 X.509 证书之外的证书类型, 那么客户端不要包含这个扩展在 ClientHello 中。

ClientHello.server_certificate_type 表示客户端可以处理的 TLS certificate type.


ServerHello 消息


当客户端收到携带 client_certificate_type 和/或 server_certificate type 扩展的 ClientHello消息, 它按照以下规则发送响应:

  1. 如果服务器端不支持这两个扩展, 那么它返回一个不携带这两个扩展的 ServerHello给客户端。
  2. 如果服务器端支持这两个扩展,但是没有和客户端支持的证书类型不匹配, 那么它中止当前 tls 会话,并返回一个携带 “unsupported_certificate” 的 Alert 消息。
  3. 如果服务器端支持这两个扩展, 并且和客户端有至少一个匹配的证书类型,它按照如下规则发送ServerHello
    1. 当 ClientHello 中包含client_certificate type, 并且服务器端想要客户端发送证书给它, 那么响应的 ServerHello 消息中必须包括 client_certificate_type. client_certificate_type 的值是从客户端的 client_certificate 的列表中选择出来的,选中的类型是客户端和服务器端都支持的类型。
    2. 当 ClientHello 中包含server_certificate type,并且它的值中包含 RawPublicKey, 服务器端返回一个携带 server_certificate_type 扩展,并且它的值也是 RawPublicKey 的 ServerHello 给客户端。

Certificate 消息

当 客户端和服务端协商好启用 RawPublicKey 之后, 服务器端发送给客户端的 Certificate 消息中将仅仅包含 SubjectPublicKeyInfo, 而不是完整的 X.509 Certificate.

同样的,如果服务器端要求客户端发送自己的证书给服务器,并要求使用 RawPublicKey, 那么客户端发送的 Certificate 消息中也将仅仅包含 SubjectPublicKeyInfo, 而不是完整的 X.509 Certificate.


其他 TLS 握手消息


对于其他握手消息没有影响, 按照标准的 TLS/DTLS 握手流程进行即可。


Client/Server Authentication


因为启用了 RawPublicKey 之后, TLS 握手过程中就不再发送完整的证书了,就的证书校验逻辑也不再适用。

RFC 对于如何校验没有做任何要求, 完全取决于应用层的设计。


实例


普通 TLS 握手


在这里插入图片描述

ClientHello

在这里插入图片描述

注意, 这里 ClientHello 中没有包含 client_certificate_type 扩展, 因为客户端没有配置证书,并且服务器端不要求客户端发送自己的证书。

客户端发送的 server_certificate_type 表示自己支持 Raw public Key 和 X.509 两种类型。

ServerHello

在这里插入图片描述

服务器端也支持Raw public Key, 返回 server_certificate_type 中包含 Raw public Key, 表明对当前 DTLS 连接启用 Raw Public Key 模式。

Certificate

在这里插入图片描述

因为启用了 RawPublicKey 模式,Certificate消息中包含的仅仅是 SubjectPublicKeyInfo 信息, 而不是完整的证书信息。


验证客户端身份的 TLS 握手


在这里插入图片描述

ClientHello

在这里插入图片描述

ServerHello

在这里插入图片描述

后边 Certificate 消息内容与上面相似, 不再赘述。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VFSSoft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值