SSL 证书和密码套件通信

信息安全 tls 公钥基础设施 openssl
2021-08-14 03:32:12

我一直在学习 SSL/TLS 协议(来自https://www.rfc-editor.org/rfc/rfc5246)并且有一些关于该协议的概念性问题。

  1. 客户端和服务器在选择 SSL/TLS 版本和密码套件期间交换“hello”消息。更具体地说,客户端建议一个密码套件列表,然后服务器选择一个(如果服务器没有选择任何东西,握手失败)。现在,服务器是否选择与证书中使用的密码套件相对应的密码套件?

例如:运行openssl x509 -in <server_cert>.pem -text -noout为您提供有关服务器证书的信息。在示例证书上,我看到公钥算法是 rsaEncryption(2048 位),签名算法是 sha256WithRSAEncryption。这不是已经预先确定了握手中使用的密码套件的一部分吗?

  1. 让我们假设服务器和客户端就密码套件达成一致。现在,我还看到客户也可以稍后在握手时出示证书。这是否意味着客户端证书上的密码必须与所选的密码套件兼容?

(类似的问题,但没有回答我想要的:Picking cipher suites for HTTPS

2个回答

对于服务器证书:密码套件指示密钥交换的类型,这取决于服务器证书密钥类型。你基本上有以下几点:

  • 对于 TLS_RSA_* 密码套件,密钥交换使用服务器的 RSA 公钥对客户端选择的随机值进行加密,因此服务器的公钥必须是 RSA 类型,并且必须适合加密(服务器的证书不得包含Key Usage扩展名上面写着“仅签名”)。

  • 对于 TLS_DHE_RSA_* 密码套件,密钥交换使用短暂的 Diffie-Hellman,服务器使用其 RSA 密钥签署其部分 DH 密钥交换。所以服务器的公钥必须是 RSA 类型的,并且必须适合签名(同样,证书不能将密钥的使用限制为仅加密)。

  • TLS_DHE_DSS_* 和 TLS_DHE_ECDSA_* 密码套件使用短暂的 Diffie-Hellman 密钥交换,服务器的密钥必须分别为 DSA 和 EC 类型,并且必须适合签名。

  • TLS_ECDHE_* 密码套件类似于 TLS_DHE_* 密码套件,不同之处在于 Diffie-Hellman 密钥交换是椭圆曲线变体。服务器证书的条件保持不变。

  • TLS_DH_* 和 TLS_ECDH_* 密码套件是不同的(注意在 'DH' 之后缺少 'E')。对于这些套件,服务器的证书直接包含 Diffie-Hellman 公钥(或其椭圆曲线变体),然后密码套件对颁发 CA 用于签署证书的算法进行限定。例如,TL​​S_DH_RSA_* 表示“服务器有一个存储在证书中的 DH 公钥,该证书由某个 CA 使用 RSA 签名”。这是证书上的签名类型与密码套件有任何关系的唯一情况。由于实际上没有人使用这种证书,因此可以忽略这种情况。

对于客户端证书:客户端在服务器请求时提供证书。客户端证书类型与密码套件没有任何关系(静态 DH 证书的极少数情况除外,但我从未见过在实践中使用过)。客户端证书必须适合签名。作为请求客户端证书的握手消息的一部分,服务器会发送一些有关支持的算法的信息(请参阅标准)。事实上,TLS 1.2 通过提供支持的算法和散列函数组合的灵活列表进一步扩展了该机制。

更新(因为这是链接、投票和搜索优化的):

在2018 年发布的TLS 1.3中,到 2020 年实际使用得相当广泛(比 TLS 传播的早期更新更快),密码套件不再控制服务器证书或密钥交换方法。

相反,服务器证书(用于协议签名)中的密钥类型(始终)由 ClientHello 中的 signature_algorithms 扩展控制(在 1.2 中作为可选引入,正如我对 ursine 答案的评论),以及服务器上的签名如果使用证书和任何链证书,则由新的可选扩展 signature_algorithms_cert 控制,否则由 signature_algorithms 控制。并且根本不再允许 DSA aka DSS。

除了用于替换会话恢复的 PSK 选项外,密钥交换始终使用临时 Diffie-Hellman(不再使用普通 RSA 密钥加密静态 DH)使用经典/整数/modp/Z p(现在称为有限域DH、FFDH,为清楚起见)或椭圆曲线组 (ECDH),由修改后的 supported_groups(最初 support_curves 仅用于 EC)和新的 key_share 扩展指定。