Клиент Scala https с сертификатом SSL

#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

Здесь ничего не изменилось.