Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

PrevUpHomeNext

SSL/TLS 证书

证书颁发机构

证书颁发机构 (CA) 是一个受信任的实体,用于签署数字证书,使用户能够验证其真实性。用户可以存储有限的一组根证书,以便在需要时验证服务器证书,而不是为每个服务器存储每个单独的证书(由于数量庞大和频繁更新,这将是不切实际的)。

Boost.Asio 提供了多种加载证书颁发机构证书的方法

设置对等方验证非常重要,这样如果证书验证不成功,TLS/SSL 握手就会失败

// Verify the remote server's certificate
ctx.set_verify_mode(net::ssl::verify_peer);

客户端还必须验证证书中的主机名或 IP 地址是否与预期的一致。 net::ssl::host_name_verification 辅助函数对象可以根据 RFC 6125 中描述的规则执行此验证

// Verify the remote server's Hostname or IP address
stream.set_verify_callback(
    net::ssl::host_name_verification("host.name"));

服务器还可以请求并验证客户端证书以验证客户端的身份

// Verify the remote client's certificate
ctx.set_verify_mode(
    net::ssl::verify_peer |
    net::ssl::verify_fail_if_no_peer_cert);
服务器证书

服务器证书是一种数字证书,用于确认服务器的身份是客户端的合法目标。它包含一个可验证的签名,以确保它是由受信任的证书颁发机构 (CA) 颁发的。

当服务器证书由中间证书颁发机构颁发,且客户端缺少这些中间证书时,服务器应向客户端提供所有相关的证书。这允许客户端根据根证书验证链中的最终证书。

以下 Boost.Asio 方法可用于加载证书或证书链

客户端证书

服务器可以通过要求和验证客户端的证书来验证客户端的身份,从而阻止没有有效证书和私钥的用户访问。服务器通过修改对等方验证设置来强制执行此操作

// Verify the remote client's certificate
ctx.set_verify_mode(
    net::ssl::verify_peer |
    net::ssl::verify_fail_if_no_peer_cert);

如果使用客户端证书,则必须将必要的 CA 证书加载到服务器的 SSL 上下文中,以启用客户端证书的验证。

公用名和主题备用名称

主题备用名称 (SAN) 是 X.509 证书中的一个扩展,允许将多个域名、子域名或 IP 地址与单个 SSL/TLS 证书关联。在此之前,证书主题中的公用名 (CN) 字段可以包含单个主机名。

RFC 6125 建议,如果证书包含 SAN dNSName 字段,则客户端必须忽略主题 CN 字段。一些现代浏览器,如 Google Chrome,仅检查 SSL/TLS 证书中的 SAN 部分,并拒绝仅包含 CN 字段的证书。

私钥

在 SSL/TLS 握手期间,需要证书的私钥来证明证书的提供者是其合法所有者

以下 Boost.Asio 方法可用于加载私钥

如果私钥使用密码保护,则 net::ssl::context::set_password_callback 允许指定一个可调用对象来检索密码。

自签名和自颁发证书

自颁发证书是指颁发者和主题是同一实体的证书。

自签名证书是一种自颁发证书,其中可以使用证书中的公钥来验证数字签名。

[Warning] 警告

安装不受信任的、自颁发的或自签名的 CA 证书会带来重大的安全风险,因为对其可以颁发证书的域没有任何限制。这允许攻击者为任何公共域生成欺诈性证书,如果他们获得对您网络的访问权限,则可以进行中间人攻击。

Diffie-Hellman (DH) 参数

Diffie-Hellman (DH) 密钥交换是一种密码协议,允许双方通过不安全的通信通道安全地建立共享密钥。密钥交换过程涉及双方商定一组参数,称为 Diffie-Hellman 参数,其中包括一个大素数 p 和一个生成器 g。由于生成这些参数是一项计算量大的任务,因此用户可能希望在启动时提供预计算的值。

以下 Boost.Asio 方法可用于加载 DH 参数

如果未提供 DH 参数,OpenSSL 将拒绝执行任何使用基于 DHE 的密码套件的握手,但仍可使用其他密码套件,例如基于 ECDHE 的密码套件。

自颁发证书示例

在以下示例中,我们将生成自签名的 CA 证书,并使用它来颁发服务器和客户端证书。

openssl req -new -newkey rsa:4096 -keyout ca.key -x509 -out ca.crt -subj "/CN=localhost" -days 365
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -copy_extensions copy -days 365 -out server.crt
openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -subj "/CN=client.1"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -days 365 -out client.crt
openssl dhparam -out dh4096.pem 4096

服务器示例: server.cpp

请注意,服务器配置为请求和验证客户端证书。您可以通过注释掉示例中相关的行来禁用此功能。

您可以使用以下 cURL 命令测试服务器

curl https://localhost:8080 --cacert ca.crt --cert client.crt --key client.key

此外,您可以使用客户端示例: client.cpp


PrevUpHomeNext