使用 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 连接背后,都有这些机制在为你的安全保驾护航。