0

我正在尝试使用 openssl (c++) 建立 DTLS 连接。

然而,虽然有DTLSv1_listen()服务器端的功能,但我找不到任何客户端相当于实际从客户端建立到服务器的 UDP 连接。或者向 DTLS 服务器发送一些东西。有人可以帮助我了解如何建立与 DTLS 服务器的“连接”(我知道 UDP 和数据报通信的目的是无连接的,但连接是指 DNS 请求+响应之类的方案)?

我需要向服务器发送一条消息,然后接收 1 条响应消息。加密。带证书验证。这种通信方案在 DTLS 世界中如何工作?

4

2 回答 2

1

你用什么发信号。实际上,您不必为信号层使用 openssl,您可以使用 Memory Bio 并从中读取和写入。

使用 DTLS,您将在这里有两个方面,一个客户端和一个服务器。客户端将通过客户端 Hello 启动事物。服务器希望收到它,将其写入 bio,读回服务器 Hello 并通过信令层进行响应。

真正完成你的应用程序进入现实世界需要很多东西,所以我不会涵盖所有内容。

如果您有 SSL 上下文,并且您已经创建了 BIO。启动服务器:

SSL_set_accept_state(*sslContext)

并启动客户端:

SSL_set_connect_state(*sslContext);

然后,您想在客户端上开始握手。这里有很多因素决定您的应用程序将如何工作,很难提供建议,但客户应该致电:

SSL_do_handshake(*sslContext);

根据您将所有内容连接起来的方式,您的程序可能会在此时自动向客户端发送问候。您可以使用 Wireshark,仅抓取 UDP 并在顶部过滤 DTLS 以查看它。如果不是,您可能需要手动发出信号。

我自己编写了以下程序来测试 OpenSSL dll,看看编译后是否有任何问题。我无法与您分享所有代码,但它显示了您如何在内存中使用单个控制台应用程序进行握手(不通过互联网传输只是为了看看它是如何工作的)。

笔记:

在这种情况下,BIO 是内存 BIO。

握手是 SSL_do_handshake

WriteCipherText 是对 BIO_write 的调用

ReadCipherText 是对 BIO_read 的调用

您必须先打开它并执行其他基本设置状态。最后,两次握手都将返回 1 表示成功。这只是向您展示了如何使用 openssl 进行基本的内存 DTLS 握手。

Console.WriteLine("[Client] Open: " + Client.Open("ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA:AES128-GCM-SHA256:AES128-SHA256", "SRTP_AES128_CM_SHA1_80"));
            Console.WriteLine("[Server] Open: " + Server.Open("ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA:AES128-GCM-SHA256:AES128-SHA256", "SRTP_AES128_CM_SHA1_80"));

            Console.WriteLine("[Client] Handshake" + Client.Handshake());
            Console.WriteLine("Client: [Read] Client Hello");
            var clientHello = Client.ReadCipherText();
            Console.WriteLine("[Server] Write Hello: " + Server.WriteCipherText(clientHello));
            Console.WriteLine("[Server] Handshake" + Server.Handshake());
            clientHello.Free();
            Console.WriteLine("[Server] Read Server Hello");
            var serverHello = Server.ReadCipherText();
            Console.WriteLine("[Client] Write Server Hello: " + Client.WriteCipherText(serverHello));
            Console.WriteLine("[Client] Handshake" + Client.Handshake());
            serverHello.Free();
            Console.WriteLine("[Client] Read Certificate");
            var clientCertificate = Client.ReadCipherText();
            Console.WriteLine("[Server] Write Certificate: " + Server.WriteCipherText(clientCertificate));
            Console.WriteLine("[Server] Handshake: " + Server.Handshake());
            clientCertificate.Free();
            Console.WriteLine("[Server] Read Change Cipher Spec");
            var serverChangeCipherSpec = Server.ReadCipherText();
            Console.WriteLine("[Client] Write Change Cipher Spec: " + Client.WriteCipherText(serverChangeCipherSpec));
            serverChangeCipherSpec.Free();
            Console.WriteLine("[Client] Handshake" + Client.Handshake());
            Console.WriteLine("[Server] Handshake" + Server.Handshake());
            Console.ReadLine();

很多有用的资源也可以看看: https ://web.archive.org/web/20150814081716/http://sctp.fh-muenster.de/dtls-samples.html这个真的很好

http://chris-wood.github.io/2016/05/06/OpenSSL-DTLS.html https://wiki.openssl.org/index.php/SSL/TLS_Client

于 2019-01-22T01:50:10.307 回答
-1

在客户端创建UDP-socket,将其传递BIO_new_dgramSSL上下文并使用connect()or连接它BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &server_sockaddr)。连接只是强制文件描述符写入始终发送到server_sockaddr.

现在只需做一个常规的SSL_connect,它应该可以工作。

对于服务器端,它有点复杂。我发了一个帖子和一个示例实现

于 2018-12-06T21:57:13.253 回答