4

我需要一个我正在编写的程序的代码片段Boost Asio SSL。我有一个由两个客户端组成的系统,它们相互连接。我要求他们进行相互身份验证,因此,在handshake()命令结束时,两个客户端都可以确定另一个客户端拥有他们提供的证书的私钥。两个客户端都有一个context对象,让我们调用它们ctx1ctx2每个客户端都有一个公共证书和一个私钥。

是否可以设置上下文对象,以便在我调用socket.handshake()客户端时进行双向身份验证。如果不是,那么实现我的目标的正确方法是什么?

4

2 回答 2

11

看起来 boost 只使用了 OpenSSL 接口。我对 boost 了解不多,但我已经为 Perl 实现了很多 OpenSSL 内部,并在阅读了 boost 源代码的相关部分后得出以下结论:

要使用 OpenSSL 进行相互身份验证,您必须SSL_VERIFY_PEER在客户端和SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT服务器端使用。如果您仅SSL_VERIFY_PEER在服务器端使用,它只会向客户端发送证书请求,但如果客户端没有发回证书,则会静默接受。

有了提升,这可能是:

ctx.set_verify_mode(ssl::verify_peer); // client side
ctx.set_verify_mode(ssl::verify_peer|ssl::verify_fail_if_no_peer_cert); // server side

如果您以这种方式设置 verify_mode ,它将根据配置的受信任 CA(使用ctx.load_verify_file或设置ctx.load_verify_path)验证证书。

如果您对签署证书的 CA(即您自己的 CA)具有完全控制权,那么您接受该 CA 签署的任何证书可能就足够了。但是,如果您使用的 CA 还签署了您不想接受的证书,就像通常使用公共 CA 的情况一样,您还需要验证证书的内容。具体如何执行此操作取决于您的协议,但对于 HTTP 或 SMTP 等常用 Internet 协议,这涉及检查证书的 commonName 和/或 subjectAltNames。通配符处理等细节因协议而异。

Boost 提供rfc2818_verification来帮助您进行 HTTP 样式的验证,尽管从阅读代码中我认为实现有点错误(接受多个通配符,允许 IDN 通配符 - 参见 RFC6125 的要求)。

我不知道验证客户端证书的任何标准。通常只接受由特定(私有)CA 签署的任何证书。其他时候来自公共 CA 的证书与特定的电子邮件模式匹配。在这种情况下,boost 似乎对您没有多大帮助,因此您可能必须获取 OpenSSLSSL*句柄,sock.native_handle()然后使用 OpenSSL 函数来提取证书(SSL_get_peer_certificate)并检查证书的内容(各种X509_*函数)。

至少如果涉及公共 CA,您还应该检查证书的吊销状态。看起来 boost 没有提供与 CRL(证书撤销列表)的直接接口,因此您必须使用ctx.native_handle()适当的 OpenSSL 函数(X509_STORE_add_crl等)。使用 OCSP(在线状态撤销协议)要复杂得多,而且相关的 OpenSSL 功能大多没有记录,这意味着您必须阅读 OpenSSL 源代码才能使用它们:(

于 2014-08-17T08:06:06.987 回答
1

一个不能强迫对方对你进行身份验证,这取决于协议,我每一方只对对方进行身份验证。只需按照http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/ssl.html的手册

ssl::context ctx(ssl::context::sslv23);
ctx.set_verify_mode(ssl::verify_peer);
ctx.load_verify_file("ca.pem");
于 2014-08-16T19:10:56.880 回答