使用 OpenSSL 演示 Diffie-Hellman 密钥交换算法

Diffie-Hellman 密钥交换算法在 HTTPS 中被广泛使用,即使在不安全的信道中,也能在客户端和服务器之间安全地建立共享密钥。本文将使用 openssl 的 s_client 工具连接真实的 HTTPS 服务器,观察 ECDHE(临时椭圆曲线 Diffie-Hellman)是如何工作的。


准备工作

  • 一台 Linux/macOS 系统(Windows 上可使用 WSL)
  • 安装了 OpenSSL(使用 openssl version 检查)
  • 可访问互联网

手把手:使用 OpenSSL 连接 TLS 服务器

我们将连接 www.baidu.com 并观察握手过程:

第一步:运行 OpenSSL 客户端

openssl s_client -connect www.baidu.com:443 -cipher ECDHE

这个命令的含义是:

  • 连接 www.baidu.com 的 443 端口(HTTPS)
  • 限制只使用 ECDHE 的加密套件

第二步:理解输出内容

你可能会看到类似以下的输出片段:

CONNECTED(00000006)
depth=2 OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
verify return:1
depth=0 C = CN, ST = beijing, L = beijing, O = "Beijing Baidu Netcom Science Technology Co., Ltd", CN = baidu.com
verify return:1
---
Certificate chain
...
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=C = CN, ST = beijing, L = beijing, O = "Beijing Baidu Netcom Science Technology Co., Ltd", CN = baidu.com
issuer=C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5414 bytes and written 443 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: ...
    Master-Key: ...
    TLS session ticket:
    ...
    Verify return code: 0 (ok)
    Extended master secret: no
---
closed

关键字段说明

字段含义
Cipher: ECDHE-RSA-AES128-GCM-SHA256表示使用临时 Diffie-Hellman(ECDHE)进行密钥交换,RSA 用于身份认证,AES-128-GCM 用于数据加密,SHA-256 用于完整性校验。
Server public key is 2048 bit是用于身份认证的 RSA 公钥,并非用于密钥交换
Secure Renegotiation IS supported支持 TLS 的安全重新协商功能

虽然 RSA 公钥在证书中显示,但会话密钥是通过 临时 ECDH 推导出来的,这意味着具备了前向保密性(即使 RSA 密钥将来被泄露,过去的会话也无法被解密)。

想看更详细的握手信息?加上 -msg 参数

openssl s_client -connect www.baidu.com:443 -cipher ECDHE -msg

你会看到类似如下的握手过程:

>>> TLS 1.2 Handshake [ClientHello]
>>> TLS 1.2 Handshake [ServerHello]
>>> TLS 1.2 Handshake [ServerKeyExchange]

ServerKeyExchange 中,你可以看到服务器的 ECDH 公钥,它将与客户端的密钥一起推导共享密钥。

注意:在 TLS 1.3 中,握手过程更简化,没有单独的 ServerKeyExchange 消息,密钥交换数据被包含在 ServerHello 中。


总结

这个简单的示例展示了 ECDHE(Diffie-Hellman 的一种形式)在 HTTPS 中通过 TLS 的使用方式:

  • 安全地建立共享密钥
  • 防止被动监听
  • 启用前向保密性

现代浏览器中,每一次 HTTPS 连接背后,都有这些机制在为你的安全保驾护航。