#scala #ssl #https
#scala #ssl #https
Вопрос:
Я хочу подключиться к серверу, используя протокол https. У меня есть самозаверяющий сертификат этого веб-сайта (.crt-файл). Теперь я хочу подключиться к этому веб-сайту, используя этот сертификат. В настоящее время я использую клиент org.apache.http.impl.nio.client
, но я готов использовать другой клиент, если он окажется полезным.
Как подключиться к серверу по протоколу https, если у меня есть SSL-сертификат этого сервера?
Комментарии:
1. Чтобы это не звучало как вопрос «дайте мне код» или «пожалуйста, прочитайте документ для меня», что вы пробовали и где вы застряли?
2. @TheArchetypalPaul Я прочитал документ о хранилище ключей, httpclient и nio о ssl. Я просто не нахожу всеобъемлющего и простого способа обработки ssl (это не могло быть так сложно !). Я думаю, что это должно быть так же просто, как загрузить ваш сертификат из файла и отправить запрос с вашим сертификатом в качестве аргумента для этого запроса.
3. Вы не понимаете, как работают сертификаты сервера. Сервер отправляет вам свой сертификат, и вы (клиент) проверяете, действителен ли он. Если вы пытаетесь использовать сертификаты на стороне клиента, на сервере должен быть настроен ваш сертификат, чтобы затем он мог проверить, что отправленный вами сертификат действителен, и таким образом аутентифицировать вашего клиента
4. @TheArchetypalPaul Я не использую сертификаты для входа в систему, я использую его, как в Firefox, чтобы разрешить или отказаться от подключения к веб-сайту.
5. Я знаю. Как я уже сказал, вы не понимаете, как это работает. Описание, которое я дал, предназначено для подключения к веб-сайтам robertheaton.com/2014/03/27/how-does-https-actually-work
Ответ №1:
Чтобы разрешить только определенный сертификат в вашем приложении, вы должны выполнить следующую процедуру:
1- Загрузить сертификат
Для этого я открыл firefox, вставил адрес веб-сайта, с которого я хочу получить сертификат. Добавьте исключение для загрузки этого сертификата. Затем вы можете получить к нему доступ, нажав на зеленую блокировку справа от адресной строки. Снимок экрана поможет вам найти, как его загрузить.
Обратите внимание, что вы должны загрузить цепной сертификат, а не единый сертификат веб-сайта. Здесь это делается в проводнике файлов ubuntu при выборе типа файла, который вы хотите экспортировать.
2. Создайте хранилище ключей java
Выполните эту команду с файлом, который вы только что загрузили :
keytool -import -file file_you_just_downloaded.crt -alias description_of_certificate -keystore /path/toyour/java/jre/lib/security/cacerts
#password by default is: changeit
Теперь у вас есть хранилище ключей java со всеми необходимыми сертификатами для подключения к вашему веб-сайту с использованием https.
3. Создайте клиент с этим сертификатом
Эти примеры сделаны с помощью веб-клиента apache nio.
import java.io.FileInputStream
import java.security.cert.X509Certificate
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl._
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.impl.nio.client.{CloseableHttpAsyncClient, HttpAsyncClients}
import org.apache.commons.io.IOUtils
import org.apache.http.ssl.SSLContexts
def httpClientFactory(
keyStoreFileName: String
): CloseableHttpAsyncClient = {
val httpClientBuilder = HttpAsyncClients.custom()
// activating or not the certificate checking
if (checkCertificate) {
// import keystore
val keyStorePassword = jksPassword // the password you used whit the command keytool
val ks = KeyStore.getInstance(KeyStore.getDefaultType)
val keyStorePath = getClass.getClassLoader.getResource(keyStoreFileName)
val inputStream = new FileInputStream(keyStorePath.getPath)
ks.load(inputStream, keyStorePassword.toArray)
IOUtils.closeQuietly(inputStream)
// create trust manager from keystore
val tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
tmf.init(ks)
val trustManager = tmf.getTrustManagers
// associate trust manager with the httpClient
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(Array(), trustManager, null)
httpClientBuilder.setSSLContext(sslContext)
} else {
logger.warn("Warning ! Https connections will be done without checking certificate. Do not use in production.")
val sslContext = SSLContexts.createDefault()
sslContext.init(null, Array(new X509TrustManager {
override def getAcceptedIssuers: Array[X509Certificate] = Array.empty[X509Certificate]
override def checkClientTrusted(x509Certificates: Array[X509Certificate], s: String): Unit = {}
override def checkServerTrusted(x509Certificates: Array[X509Certificate], s: String): Unit = {}
}), new SecureRandom())
httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(sslContext)
}
// ending httpClient creation
httpClientBuilder.build()
}
4- Используйте HttpClient
Здесь ничего не изменилось.