为现有TCP&添加SSL支持UDP代码?

时间:2009-07-09 18:16:32

标签: c++ ssl udp tcp ssl-certificate

这是我的问题。

现在我有一个Linux服务器应用程序(使用C ++编写 - gcc)与Windows C ++客户端应用程序通信(Visual Studio 9,Qt 4.5。)

非常最简单的方法是向双方添加SSL支持以确保通信安全,而不会完全消除现有协议?

这是一个VOIP应用程序,它使用UDP和TCP的组合来初始设置连接并进行端口隧道处理,然后使用UDP作为流数据。

我过去曾经遇到很多问题,从头开始创建安全证书,这些都是让这些东西运转所必需的。

现有的工作示例代码是理想的。

谢谢!

5 个答案:

答案 0 :(得分:11)

SSL is very complex,所以你想要使用一个库。

有几个选项,例如KeyczarBotancryptlib等。这些库中的每一个(或其他人建议的库,例如Boost.Asio)或OpenSSL)将为此提供示例代码。


回答你的第二个问题(如何将库集成到现有代码中而不会造成太多痛苦):它将取决于你当前的代码。如果您已经有调用Winsock或socket方法来发送/接收intstrings等的简单函数,那么您只需要重写这些函数的内容。当然,请更改设置套接字的代码。

另一方面,如果您直接调用Winsock / socket函数,那么您可能希望编写具有类似语义但发送数据加密的函数,并用这些函数替换Winsock调用。

但是,您可能需要考虑转换为Google Protocol BuffersApache Thrift(a.k.a.Facebook Thrift)。谷歌的协议缓冲区文档说,“在协议缓冲之前,有一种请求和响应的格式,使用手动编组/解组请求和响应,并支持许多版本的协议。这导致一些非常丑陋的代码。 ......“

您目前处于手动编组/解组阶段。它可以工作,事实上我工作的项目确实使用这种方法。但将它留给图书馆要好得多;特别是一个已经考虑过将来更新软件的图书馆。

如果你走这条路线,你将使用SSL库建立你的网络连接,然后你将通过这些连接推送你的Thrift / Protocol Buffer数据。而已。它确实涉及广泛的重构,但你最终会用更少的代码来维护。当我们在我提到的项目的代码库中引入Protocol Buffers时,我们能够摆脱大约300行编组/解编码。

答案 1 :(得分:4)

我建议在客户端和服务器端使用GnuTLS,仅用于TCP连接。暂时忘掉UDP数据。 GnuTLS文档具有example code,用于编写客户端和服务器。请理解,至少服务器端(通常是TCP响应者)需要有证书;客户端可以使用匿名标识(尽管甚至有一个没有服务器证书的例子,只使用DH密钥交换 - 这将允许中间人攻击)。

通常,无论您使用哪个库,都可能需要了解SSL的原理。库替代品是OpenSSL(包括Unix和Windows)和SChannel(仅限Windows)。

答案 2 :(得分:2)

您是否在Boost.AsioACE中尝试过SSL支持?两者都在引擎盖下使用OpenSSL,并为TCP,UDP和SSL提供类似的抽象。示例代码在Boost.Asio和ACE发行版中都可用。

您可能需要记住的一件事是SSL是面向记录而不是面向流(TCP和UDP)。这可能会影响您复用事件的方式,因为您必须先读取完整的SSL记录,然后才能调用读取操作。

答案 3 :(得分:2)

为了帮助处理这个问题而不更改应用程序,您可能希望查看stunnel项目(http://www.stunnel.org/)。我不认为它会为你处理UDP。

答案 4 :(得分:2)

过去,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

的问候,
克里斯