Сокеты Java SSL без аутентификации или хранилища? - PullRequest
4 голосов
/ 10 марта 2010

У меня есть два java-приложения, которым нужно общаться друг с другом через зашифрованный TCP-сокет, но им не нужно аутентифицировать друг друга (одно будет принимать () соединение от другого). Может кто-нибудь указать мне учебник / фрагмент кода, который поможет мне настроить их?

Я ищу что-то довольно простое, и мне бы не хотелось предоставлять какие-либо материалы для хранилища ключей или доверенных сертификатов.

РЕДАКТИРОВАТЬ: я должен быть более конкретным здесь. Я имел в виду, что они не должны аутентифицировать друг друга через SSL . У меня есть некоторая нетривиальная аутентификация, которую я должен сделать на уровне приложения, поэтому я не могу использовать какую-либо схему аутентификации на основе SSL.

Кроме того, для некоторых ссылок в ответах, опубликованных до сих пор (по состоянию на полдень 3/10/2010), требуются файлы хранилища ключей. Есть ли простой способ, которым я могу программно генерировать нужные мне ключи?

Ответы [ 3 ]

2 голосов
/ 10 марта 2010

Чтобы повторить совет Криса Джестера-Янга - если у вас нет аутентификации, то вы можете общаться безопасно, но у вас есть нет представление о том, с кем вы безопасно общаетесь. Вы могли бы просто очень безопасно общаться с самим плохим парнем (который передает все, что вы говорите, человеку, с которым вы надеялись , с которым вы разговаривали).

Однако, существует довольно легкая схема аутентификации, которая может соответствовать вашим целям, называемая TOFU (Trust On First Use). Здесь вы используете SSL и генерируете самозаверяющие сертификаты для каждой стороны - однако вы не пропускаете проверку сертификата. Вместо этого, при первом соединении с данным узлом вы принимаете любой сертификат и сохраняете его локально; при последующих соединениях с этим узлом вы только принимаете этот сохраненный сертификат. Это похоже на способ, которым ssh по умолчанию работает для аутентификации хоста, и обеспечивает аутентификацию "парень, с которым я сейчас разговариваю, тот же, с которым я разговаривал вчера" * разновидность.

1 голос
/ 10 марта 2010

Вы можете использовать анонимные шифровальные наборы Диффи-Хеллмана, если вы настаиваете на игнорировании мудрого совета Криса Джестера-Янга.Эти наборы шифров не включены по умолчанию, вы должны явно включить их, например, с помощью метода SSLSocket.setEnabledCipherSuites().

0 голосов
/ 02 ноября 2010

Если вы абсолютно не хотите использовать SSL с сертификатами, вы можете свернуть свой собственный, хотя, очевидно, он не будет таким безопасным. Я просто импровизирую, смешивая небольшую асимметричную криптографию со стуком порта.

Во-первых, создайте случайную пару ключей RSA на клиенте в памяти, нет необходимости хранить ее где-либо. Затем клиент подключается к серверу с помощью простого сокета и при подключении отправляет серверу открытый ключ (закодируйте его по своему желанию, чтобы вы могли легко прочитать его на сервере). Затем сервер генерирует случайный 128-битный ключ, запускает ДРУГОЙ ServerSocket в произвольном порту и шифрует 128-битный ключ и новый номер порта сервера, используя открытый ключ клиента, и отправляет данные обратно клиенту. Сервер должен ждать в течение короткого периода времени, чтобы получить соединение от того же клиента на новый порт.

Клиент закрывает соединение, расшифровывает данные и открывает новый сокет для сервера на указанном порту. Затем и клиент, и сервер должны обернуть InputStream и OutputStream сокета в CipherInputStream и CipherOutputStream, используя AES / CBC / PKCS5Padding (или RC4, если хотите), с указанным 128-битным ключом. Вуаля, у вас есть безопасное соединение между клиентом и сервером, без какой-либо аутентификации.

Если вы хотите обработать аутентификацию, вы можете сделать это через безопасное соединение, или при первом соединении сервер также может иметь пару ключей RSA, они обмениваются ключами, и сервер может отправить запрос клиенту (сервер отправляет вызов клиенту с использованием открытого ключа клиента, и клиент отвечает на вызов с использованием открытого ключа сервера). Но это излишне сложно, и я думаю, что вам все равно лучше использовать стандартный SSL с хранилищами ключей ... возможно, вы можете создать хранилище ключей в памяти на клиенте и отправить его на сервер, как описано выше, используя первое соединение (шифрование хранилище ключей с открытым ключом сервера), а затем вы можете настроить второе соединение для использования SSL с этим хранилищем ключей, которое является временным и будет отброшено при отключении клиента.

...