Криптография и аутентификация через TLS с Web of Trust в Java - PullRequest
6 голосов
/ 19 апреля 2011

Для программы, которую я пишу, я хотел бы использовать TLS (или что-то подобное) для инкапсуляции протокола моего приложения. Это сведет к минимуму объем работы, которую я должен выполнить, а также количество уязвимостей, которые я мог случайно создать.

Моя программа разработана для одноранговой связи, хотя один или несколько серверов предоставляют некоторые услуги, чтобы помочь одному пользователю найти другого (он регистрирует комбинации IP-адресов / портов), но мало что делают. Я хочу сделать эту систему очень отказоустойчивой, поэтому использование этих серверов в качестве центра сертификации недопустимо, поскольку компрометация сервера или его ключа может повлиять на слишком много пользователей. Поэтому я планирую использовать сеть доверия.

Основная проблема с использованием TLS заключается в том, что исходная спецификация TLS 1.2 (RFC 5246) не предусматривает использование сертификатов OpenPGP. Кажется, что он очень х.509 центрирован. RFC 6091, который устарел RFC 5081 и расширяет RFC 5246, предусматривает расширение для TLS, которое делает то, что я хочу. Проблема в том, что я не думаю, что BouncyCastle реализует это расширение, и я не могу найти криптографическую библиотеку Java, которая это делает. Я также не хочу писать свои собственные материалы / делать свой вклад в BC, потому что я действительно не умею делать ошибки и я очень ленив.

Другая проблема заключается в том, что BouncyCastle предоставляет «облегченный API-интерфейс TLS на стороне клиента», но поскольку это программное обеспечение является P2P, также необходим API-интерфейс на стороне сервера, чтобы я мог использовать TLS, заставляя его верить, что инициирующий узел соединение клиент. Я уверен, что после того, как рукопожатие будет завершено, оно будет таким же.

Вопросы: Есть ли способ, которым я все еще могу использовать TLS (в чем я сильно сомневаюсь)? Существует ли такой протокол, как TLS, который предназначен для P2P, или, по крайней мере, он может функционировать таким образом (как я полагаю, может TLS), но может работать с сертификатом OpenPGP? Если это не так, должен ли я следовать идее, изложенной в этом вопросе , и реализовать свой собственный уровень, используя концепции TLS?

Ссылки на RFC: RFC 5246 и RFC 6091

Ответы [ 3 ]

4 голосов
/ 20 апреля 2011

Единственная известная мне библиотека для поддержки RFC 6091 (т.е. TLS с сертификатами openpgp) - это GnuTLS , но я не знаю, можно ли использовать что-то подобное в Java. В качестве альтернативы вы можете повторить семантику SSH, где вы храните открытые ключи ваших пиров, используя самоподписанные Сертификаты X.509.

1 голос
/ 29 мая 2011

Насколько мне известно, реализация JSSE Sun / Oracle имеет дело только с доверенными менеджерами X.509 (которые можно настроить для обработки определенных расширений, но при этом все равно можно ожидать структурно действительный сертификат X.509.

Возможно, можно использовать API безопасности Java для реализации RFC 6091, но я не уверен, как это сделать. Это определенно больше работы, чем просто настройка TrustManagers, поскольку вам придется углубиться в реализацию TLS в Java.

В качестве альтернативы, если это сервер на заказ, вы можете повторно использовать материал ключа из сертификатов PGP в сертификатах X.509 и поместить исходный сертификат PGP (со всеми его сигнатурами) в качестве большого двоичного объекта в собственное расширение X.509 (какэто более или менее сделано здесь ). Проблема здесь была бы в функциональной совместимости, поскольку такое расширение не было бы стандартом. Реализация TrustManager в Java, способной понимать расширение, определенно выполнима, и выне нужно копаться во внутреннем стеке TLS Java, вы бы толькодля инициализации ваших SSLContexts приходится иметь дело с пользовательскими TrustManager.

1 голос
/ 20 апреля 2011

В TLS части X.509 фактически обрабатываются как непрозрачные двоичные объекты:

  • Сервер отправляет свой сертификат (и некоторые вспомогательные сертификаты, если он этого пожелает) в виде (списка) непрозрачных строк (байтов) (длиной в три байта, за которыми следует кодированный сертификат в виде произвольных байтов).
  • Когда сервер запрашивает аутентификацию клиента с открытым ключом, он отправляет список «имен», которые должны быть зашифрованными именами X.500 корневого ЦС, которые сервер будет распознавать, - опять же, непрозрачные двоичные объекты (два длина байта).
  • Клиент, когда (если) отправляет сертификат (цепочку), использует тот же формат, что и сервер.

Поскольку TLS определен, предполагается, что и клиент, и сервер должны использовать открытый ключ партнера, который они получают любым способом, который они считают подходящим , и это в основном выходит за рамки спецификации TLS: обмен сертификатами через провод считаются просто помощниками. Таким образом, при отправке открытых ключей, закодированных в OpenPGP, в этих двоичных объектах проблем не возникнет, если этого ожидают и клиент, и сервер, а поскольку вы управляете кодом для обоих, это не должно быть проблемой.

Тогда ваша проблема просто сводится к тому, чтобы реализация TLS согласилась передать вам большие двоичные объекты, не подавляя их. Я не знаю ни одной существующей реализации TLS только для Java, которая бы отвечала всем требованиям, поэтому вам, возможно, придется написать немного кода, но я призываю вас не возиться с деталями протокола TLS, за исключением обработки бланков сертификатов. Эти вещи тонкие, а слабости ооочень легко создать ...

...