I want to connect to a server using https protocol. I have the self-signed certificate of this website (.crt file). Now I want to connect to this website using this certificate. I am currently using the client org.apache.http.impl.nio.client
, but I am ready to use another client if it proves to be useful.
How to connect to a server over https given I have the ssl certificate of this server ?
In order to allow only a specific certificate in your application, you have to follow the following procedure:
To do this, I opened firefox, paste the address of the website from which I want to get the certificate. Add exception to download this certificate. You can then access it by clicking on the green lock on the right of the address bar. The screen-shot will help you find how to download it.
Note that you should download the chain certificate, not the single certificate of the website. Here this is done in the file explorer of ubuntu, when choosing the type of file you want to export.
Execute this command with the file you just downloaded :
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
You now have a java key store with all the required certificate to connect to your website using https.
Those example are made with the apache nio web client.
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()
}
Nothing change here.