SSL и SocketChannel
-
22-08-2019 - |
Вопрос
В идеале мне нужен только простой SSLSocketChannel
.
У меня уже есть компонент, который читает и записывает сообщения поверх обычных SocketChannel
, но для некоторых из этих соединений мне приходится использовать проводной протокол SSL;однако операции над этими соединениями одинаковы.
Кто-нибудь знает бесплатную SSLSocketChannel
реализация (с соответствующим селектором) или что-то подобное?Я нашел этот, но селектор не принимает его, поскольку его поставщик не SUN.
Я отделяю сетевую логику read_from/writing_to от вставки и извлечения сетевых данных через простой объект, чтобы использовать SSLEngine
не сердитесь, но реализовать это правильно очень сложно, учитывая тот факт, что я не знаю внутренностей протокола SSL...
Решение
Ознакомьтесь с реализацией Restlet, она может делать то, что вам нужно, и все дело в NIO.
Документация по Restlet Engine
В частности, HttpClientCall.SetProtocol(HTTPS) — getResponseEntityChannel возвращает ReadableByteChannel (getEntityChannel возвращает WriteableByteChannel)
Другие советы
У Jetty есть реализация NIO SSL для своего сервера: SSLSelectorChannelConnector.Возможно, вы захотите взглянуть на него, чтобы узнать подробности о том, что он делает.
Еще есть старая (но приличная) статья от О'Рейли здесь объясняются подробности о NIO + SSL вместе с примером кода.
TLS-канал это простая библиотека, которая делает именно это:упаковка SSLContext (или SSLEngine) и раскрытие интерфейса ByteChannel, выполняющего тяжелую работу внутри.
(Отказ от ответственности:Я главный автор библиотеки).
Не уверен, что это то, что вы ищете, но может помочь...Чтобы создать серверные сокеты с поддержкой SSL/TLS, я в настоящее время использую код, подобный следующему (keystore.jks содержит самозаверяющую пару частного/открытого ключей, используемую для обеспечения подтверждения) - у клиентов есть аналогичное хранилище доверенных сертификатов, которое содержит подписанный сертификат с открытый ключ этой пары.
Немного погуглив, чтобы настроить эту настройку, должно помочь вам приступить к делу.
String keyStorePath = "keystore.jks";
String keyStorePassword = "password";
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = new KeyStore();
keyStore.load(new FileInputStream(keyStorePath), keyStorePassword);
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
SSLContext sslContext = getServerSSLContext(namespace.getUuid());
SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();
// Create sockets as necessary