Добавление поддержки SSL к существующему коду TCP и UDP? - PullRequest
12 голосов
/ 09 июля 2009

Вот мой вопрос.

Сейчас у меня есть серверное приложение Linux (написанное с использованием C ++ - gcc), которое взаимодействует с клиентским приложением Windows C ++ (Visual Studio 9, Qt 4.5.)

Каков очень самый простой способ добавить поддержку SSL обеим сторонам для обеспечения безопасности обмена данными без полного удаления существующего протокола?

Это приложение VOIP, которое использует комбинацию UDP и TCP для первоначальной настройки соединения и выполнения туннелирования портов, а затем использует UDP для потоковой передачи данных.

В прошлом у меня было много проблем с созданием сертификатов безопасности с нуля, которые были необходимы для того, чтобы все это работало.

Идеальный рабочий пример кода был бы идеальным.

Спасибо!

Ответы [ 5 ]

11 голосов
/ 09 июля 2009

SSL очень сложен , поэтому вы захотите использовать библиотеку.

Есть несколько вариантов, таких как Keyczar , Botan , cryptlib и т. Д. Каждая из этих библиотек (или библиотеки, предложенные другими например, Boost.Asio или OpenSSL) будет иметь пример кода для этого.


Отвечая на ваш второй вопрос (как интегрировать библиотеку в существующий код без особых проблем): это будет зависеть от вашего текущего кода. Если у вас уже есть простые функции, которые вызывают методы Winsock или socket для отправки / получения int s, strings и т. Д., То вам просто нужно переписать кишки этих функций. И, конечно, для начала измените код, который устанавливает сокет.

С другой стороны, если вы вызываете функции Winsock / socket напрямую, вы, вероятно, захотите написать функции, которые имеют аналогичную семантику, но отправлять данные в зашифрованном виде, и заменить вызовы Winsock этими функциями.

Однако вы можете рассмотреть возможность перехода на что-то вроде Буферы протокола Google или Apache Thrift (a.k.a. Facebook Thrift). Документация Google Protocol Buffers гласит: «До буферов протокола существовал формат для запросов и ответов, в котором использовалось ручное маршалинг / демаршаллинг запросов и ответов и который поддерживал ряд версий протокола. Это привело к некоторому очень уродливому коду. ... "

Вы находитесь в фазе маршаллинга / демаршаллинга рук. Это может работать, и фактически проект, над которым я работаю, использует этот метод. Но гораздо приятнее оставить это библиотеке; особенно библиотека, которая уже подумала об обновлении программного обеспечения в будущем.

Если вы пойдете по этому пути, вы настроите сетевые соединения с библиотекой SSL, а затем передадите данные Thrift / Protocol Buffer по этим соединениям. Вот и все. Это включает в себя обширный рефакторинг, но в итоге у вас будет меньше кода для обслуживания. Когда мы добавили Protocol Buffers в кодовую базу того проекта, о котором я упоминал, мы смогли избавиться от примерно 300 строк кода маршалинга / демаршаллинга.

4 голосов
/ 09 июля 2009

Я рекомендую использовать GnuTLS как на стороне клиента, так и на стороне сервера, только для соединения TCP. Забудьте о данных UDP на данный момент. Документация GnuTLS содержит пример кода для написания как клиентов, так и серверов. Пожалуйста, поймите, что по крайней мере сторона сервера (обычно ответчик TCP) должна иметь сертификат; клиентская сторона может работать с анонимной идентификацией (хотя есть даже пример без сертификата сервера, использующего только обмен ключами DH - который позволил бы атаки «человек посередине»).

В целом, вам, вероятно, придется понимать принципы SSL, независимо от того, какую библиотеку вы используете. Альтернативами библиотеки являются OpenSSL (как для Unix, так и для Windows) и SChannel (только для Windows).

2 голосов
/ 28 сентября 2010

В прошлом у меня хорошо работали встроенные библиотеки SSL / TLS yaSSL и CyaSSL. Ориентированные на встраиваемые системы, они оптимизированы как по скорости, так и по размеру. yaSSL написан на C ++, а CyaSSL написан на C. Для сравнения, CyaSSL может быть в 20 раз меньше OpenSSL.

Оба поддерживают самые современные отраслевые стандарты (до TLS 1.2), предлагают некоторые интересные функции, такие как потоковые шифры, и имеют двойную лицензию по GPLv2 и коммерческую лицензию (если вам нужна коммерческая поддержка).

У них есть учебник по SSL, который также касается добавления CyaSSL в уже существующий код: http://www.yassl.com/yaSSL/Docs-cyassl-manual-11-ssl-tutorial.html

Страница продукта: http://yassl.com/yaSSL/Products.html

С уважением,
Chris

2 голосов
/ 18 июля 2009

Чтобы помочь справиться с этим без изменений в приложении, вам, возможно, захочется взглянуть на проект stunnel (http://www.stunnel.org/). Я не думаю, что он будет обрабатывать UDP для вас.

2 голосов
/ 09 июля 2009

Вы пробовали поддержку SSL в Boost.Asio или ACE ? Оба используют скрытую OpenSSL и предоставляют аналогичные абстракции для TCP, UDP и SSL. Пример кода доступен в дистрибутивах Boost.Asio и ACE.

Одна вещь, которую вы, возможно, должны иметь в виду, это то, что SSL ориентирован на запись, а не на поток (как TCP, так и UDP). Это может повлиять на мультиплексирование событий, поскольку, например, необходимо прочитать полную запись SSL, прежде чем можно будет завершить операцию чтения.

...