3. TLS 1.3 中的自举
TLS-POK 使用带 EPSK 的基于证书的认证. EPSK 从 BSK public key 派生, 并按 RFC 9258 导入. 客户端将 BSK 作为 raw public key 呈现, 并使用 ECDSA 进行认证.
3.1. EPSK 派生 (EPSK Derivation)
EPSK 元组由 Base Key, External Identity 和 Hash 组成. Base Key 是 BSK public key 的 DER 编码 ASN.1 SubjectPublicKeyInfo 表示. 派生时不得添加 zero-byte padding.
epskid = HKDF-Expand(HKDF-Extract(<>, Base Key),
"tls13-bspsk-identity", L)
where:
- epskid is the EPSK External Identity
- Base Key is the DER-encoded ASN.1 subjectPublicKeyInfo
representation of the BSK public key
- L equals 32, the length in octets of the SHA-256 output
- <> is a NULL salt, which is a string of L zeros
必须使用 SHA-256.
struct {
opaque external_identity<1...2^16-1>;
opaque context<0..2^16-1>;
uint16 target_protocol;
uint16 target_kdf;
} ImportedIdentity;
取值为 external_identity = epskid, context = "tls13-bsk", target_protocol = TLS1.3(0x0304), target_kdf 按 RFC 9258 指定. context 值必须为 "tls13-bsk".
3.2. TLS 1.3 握手细节 (TLS 1.3 Handshake Details)
客户端在 ClientHello 中包含 "tls_cert_with_extern_psk" 和 "client_certificate_type", 并指定 RawPublicKey. 如果服务器找不到匹配的 EPSK, 它必须使用 alert 终止握手. TLS 1.3 key schedule 必须同时在 Early Secret 派生中包含 EPSK, 并在 Handshake Secret 派生中包含 DHE/ECDHE shared secret.
服务器必须发送 CertificateRequest. 客户端必须使用其 BSK 作为 raw public key 进行认证. 客户端在处理 ServerHello 并验证 TLS key schedule 之前不得共享 BSK public key; 如果 PSK 验证失败, 不得向服务器发送 BSK public key. 服务器必须确认 Certificate public key 与本次 EPSK 和 ImportedIdentity 所用的 BSK public key 完全相同.
Client Server
-------- --------
ClientHello
+ cert_with_extern_psk
+ client_cert_type=RawPublicKey
+ key_share
+ pre_shared_key -------->
ServerHello
+ cert_with_extern_psk
+ client_cert_type=RawPublicKey
+ key_share
+ pre_shared_key
{EncryptedExtensions}
{CertificateRequest}
{Certificate}
{CertificateVerify}
<-------- {Finished}
{Certificate}
{CertificateVerify}
{Finished} -------->