【问题标题】:OpenSSL C++ DTLS clientOpenSSL C++ DTLS 客户端
【发布时间】:2017-06-06 04:13:19
【问题描述】:

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

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

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

【问题讨论】:

  • DTLS 和 UDP 一样,是“一劳永逸”。你没有建立连接。它不是面向连接的协议。你发送消息。它可能会到达,也可能不会。由您来处理簿记以重试直到消息到达。正如他们所说,那些不使用 TCP/IP 的人注定要重新发明它。
  • 是的,但我如何真正“开火”?我没有看到像 SSL_DTLSv1_sendto() 这样的任何 openssl 函数
  • 检查 OpenSSL 的 dtlstest.c。它与 TLS 连接没有什么不同。只需写入或读取 BIO。您可能还对methods.c 感兴趣。请注意,一旦获得创建上下文的方法,TLS 和 DTLS 看起来几乎相同。

标签: c++ openssl udp dtls


【解决方案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

【讨论】:

    【解决方案2】:

    在客户端,您创建UDP-socket,将其与BIO_new_dgram 一起传递给SSL 上下文,并将其与connect() 或BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &server_sockaddr) 连接。连接只是强制文件描述符写入始终发送到server_sockaddr。

    现在只需执行常规的SSL_connect 即可。

    对于服务器端,它有点复杂。我做了一个post 和一个example implementation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 2013-06-06
      • 1970-01-01
      • 2019-06-08
      • 2019-05-11
      • 2019-10-13
      相关资源
      最近更新 更多