将 SSL 支持添加到现有的 TCP 和 TCP 中 UDP 代码?
这是我的问题。
现在,我有一个 Linux 服务器应用程序(使用 C++ - gcc 编写),它与 Windows C++ 客户端应用程序(Visual Studio 9、Qt 4.5)进行通信。
添加 SSL 支持的最简单方法是什么?双方为了确保通信安全而不完全破坏现有协议?
它是一个 VOIP 应用程序,它使用 UDP 和 TCP 的组合来初始建立连接并执行端口隧道操作,然后使用 UDP 传输流数据。
过去,我在从头开始创建安全证书时遇到了很多问题,而这些证书是让这些东西正常工作所必需的。
现有的工作示例代码将是理想的。
谢谢你!
Here's my question.
Right now I have a Linux server application (written using C++ - gcc) that communicates with a Windows C++ client application (Visual Studio 9, Qt 4.5.)
What is the very easiest way to add SSL support to both sides in order to secure the communication, without completely gutting the existing protocol?
It's a VOIP application that uses a combination of UDP and TCP to initially set up the connection and do port tunneling stuff, and then uses UDP for the streaming data.
I've had lots of problems in the past with creating the security certificates from scratch that were necessary to get this stuff working.
Existing working example code would be ideal.
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
SSL 非常复杂,因此您'我们想要使用图书馆。
有多种选项,例如 Keyczar、Botan, cryptlib这些库中的每一个(或者其他人建议的库,例如 Boost.Asio 或 OpenSSL)都会有相应的示例代码。
回答你的第二个问题(如何将库集成到现有代码中而不造成太多痛苦):这将取决于你当前的代码。 如果您已经有调用 Winsock 或套接字方法来发送/接收 int、字符串等的简单函数,那么您只需要重写这些函数的内部即可。 当然,首先要更改设置套接字的代码。
另一方面,如果您直接调用 Winsock/socket 函数,那么您可能需要编写具有类似语义但加密发送数据的函数,并用这些函数替换您的 Winsock 调用。
不过,您可能需要考虑改用 Google Protocol Buffers 或 Apache Thrift(又名 Facebook Thrift)。 谷歌的 Protocol Buffers 文档称:“在 Protocol Buffers 出现之前,有一种请求和响应格式,它使用请求和响应的手动编组/解组,并且支持多个版本的协议。这导致了一些非常丑陋的代码。 ...”
您当前处于手动编组/解组阶段。 它可以工作,事实上我从事的一个项目确实使用了这种方法。 但把它留给图书馆会好得多; 尤其是一个已经考虑过在未来更新软件的图书馆。
如果您选择此路线,您将使用 SSL 库设置网络连接,然后通过这些连接推送 Thrift/Protocol Buffer 数据。 就是这样。 它确实涉及大量的重构,但最终您需要维护的代码会减少。 当我们将 Protocol Buffers 引入到我提到的那个项目的代码库中时,我们能够摆脱大约 300 行编组/解组代码。
SSL is very complex, so you're going to want to use a library.
There are several options, such as Keyczar, Botan, cryptlib, etc. Each and every one of those libraries (or the libraries suggested by others, such as Boost.Asio or OpenSSL) will have sample code for this.
Answering your second question (how to integrate a library into existing code without causing too much pain): it's going to depend on your current code. If you already have simple functions that call the Winsock or socket methods to send/receive
int
s,strings
, etc. then you just need to rewrite the guts of those functions. And, of course, change the code that sets up the socket to begin with.On the other hand, if you're calling the Winsock/socket functions directly then you'll probably want to write functions that have similar semantics but send the data encrypted, and replace your Winsock calls with those functions.
However, you may want to consider switching to something like Google Protocol Buffers or Apache Thrift (a.k.a. Facebook Thrift). Google's Protocol Buffers documentation says, "Prior to protocol buffers, there was a format for requests and responses that used hand marshalling/unmarshalling of requests and responses, and that supported a number of versions of the protocol. This resulted in some very ugly code. ..."
You're currently in the hand marshalling/unmarshalling phase. It can work, and in fact a project I work on does use this method. But it is a lot nicer to leave that to a library; especially a library that has already given some thought to updating the software in the future.
If you go this route you'll set up your network connections with an SSL library, and then you'll push your Thrift/Protocol Buffer data over those connections. That's it. It does involve extensive refactoring, but you'll end up with less code to maintain. When we introduced Protocol Buffers into the codebase of that project I mentioned, we were able to get rid of about 300 lines of marshalling/demarshalling code.
我建议在客户端和服务器端都使用 GnuTLS,仅用于 TCP 连接。 暂时忘记 UDP 数据。 GnuTLS 文档有 示例代码 用于编写客户端和服务器。 请理解,至少服务器端(通常是TCP响应方)需要有证书; 客户端可以使用匿名身份验证(尽管甚至有一个没有服务器证书的示例,仅使用 DH 密钥交换 - 这将允许中间人攻击)。
一般来说,无论您使用什么库,您都可能必须了解 SSL 的原理。 库的替代方案是 OpenSSL(Unix 和 Windows)和 SChannel(仅限 Windows)。
I recommend to use GnuTLS on both the client and the server side, only for the TCP connection. Forget about the UDP data for now. The GnuTLS documentation has example code for writing both clients and servers. Please understand that at least the server side (typically the TCP responder) needs to have a certificate; the client side can work with anonymous identification (although there is even an example without server certificate, using only DH key exchange - which would allow man-in-the-middle attacks).
In general, it is likely that you will have to understand the principles of SSL, no matter what library you use. Library alternatives are OpenSSL (both Unix and Windows), and SChannel (only Windows).
您是否尝试过 Boost.Asio 中的 SSL 支持 或 ACE? 两者都在底层使用 OpenSSL,并为 TCP、UDP 和 SSL 提供类似的抽象。 Boost.Asio 和 ACE 发行版中均提供了示例代码。
您可能需要记住的一件事是 SSL 是面向记录的而不是面向流的(TCP 和 UDP)。 这可能会影响您多路复用事件的方式,因为您必须先读取完整的 SSL 记录,然后才能调用读取操作完成。
Have you tried the SSL support in Boost.Asio or ACE? Both use OpenSSL under-the-hood, and provide similar abstractions for TCP, UDP and SSL. Sample code is available in both the Boost.Asio and ACE distributions.
One thing you may need to keep in mind is that SSL is record-oriented instead of the stream-oriented (both TCP and UDP). This may affect how you multiplex events since you must, for example, read the full SSL record before you can call a read operation complete.
为了在不更改应用程序的情况下帮助处理此问题,您可能需要查看 stunnel 项目 (http://www.stunnel .org/)。 我不认为它会为你处理 UDP。
To help handle this with no changes to the application yo may want to look at the stunnel project (http://www.stunnel.org/). I don't think that it will handle the UDP for you though.
yaSSL 和 CyaSSL 嵌入式 SSL/TLS 库过去对我来说效果很好。 它们针对嵌入式系统,针对速度和尺寸进行了优化。 yaSSL 是用 C++ 编写的,而 CyaSSL 是用 C 编写的。相比之下,CyaSSL 最多可以比 OpenSSL 小 20 倍。
两者都支持最新的行业标准(高达 TLS 1.2),提供一些很酷的功能,例如流密码,并且获得 GPLv2 和商业许可证的双重许可(如果您需要商业支持)。
他们有一个 SSL 教程,涉及将 CyaSSL 添加到您预先存在的代码中:http://www.yassl.com/yaSSL/Docs-cyassl-manual-11-ssl-tutorial.html
产品页面:http://yassl.com/yaSSL/Products.html
问候,
克里斯
The yaSSL and CyaSSL embedded SSL/TLS libraries have worked well for me in the past. Being targeted at embedded systems, they are optimized for both speed and size. yaSSL is written in C++ and CyaSSL is written in C. In comparison, CyaSSL can be up to 20 times smaller than OpenSSL.
Both support the most current industry standards (up to TLS 1.2), offer some cool features such as stream ciphers, and are dual licensed under the GPLv2 and a commercial license (if you need commercial support).
They have an SSL tutorial which touches on adding CyaSSL into your pre-existing code as well: http://www.yassl.com/yaSSL/Docs-cyassl-manual-11-ssl-tutorial.html
Product Page: http://yassl.com/yaSSL/Products.html
Regards,
Chris