Giriş
Açıklaması şöyle
The Java 11 HTTP Client API provides extensive support for SSL/TLS configurations, ensuring secure communication over HTTPS. Developers can customize SSL/TLS parameters, specify trust stores, and handle scenarios where client certificates are required for authentication. This allows applications to securely communicate with HTTPS-based services.
Örnek
Şöyle yaparız.
HttpClient client = HttpClient.newBuilder() .sslContext(SSLContext.getDefault()) .build();
Örnek - Self Signed Certificate
Sunucu için key store oluşturalım
keytool -genkeypair -keyalg RSA -keysize 2048 -alias server1 -keystore server1.keystore \ -storepass password -validity 3650 -dname "CN=localhost" \ -ext SAN=ip:127.0.0.1,dns:localhost
İstemci için trust store oluşturalım
#export certificate from server keytool -exportcert -keystore server1.keystore -alias server1 -file server.crt \ -storepass password #import certificate to client trust store keytool -import -file server.crt -keystore client1.truststore -storepass password \ -storetype JKS -alias server1
Sunucuyu başlatalım
Properties serverProps = new Properties(); serverProps.setProperty("javax.net.ssl.keyStore","path to server1.keystore")); serverProps.setProperty("javax.net.ssl.keyStorePassword", "password"); serverProps.setProperty("javax.net.ssl.trustStorePassword", "password"); serverProps.setProperty("javax.net.ssl.protocol", "TLS"); // Start the server
İstemciyi başlatalım. Elimizde şöyle bir kod olsun
public static TrustManagerFactory loadTrustManagerFactory( String trustStorePassword, String trustStore, String trustManagerAlgorithm, String trustStoreType) throws IOException, GeneralSecurityException { if (trustStore == null) { return null; } TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustManagerAlgorithm); KeyStore ts = KeyStore.getInstance(trustStoreType); char[] passPhrase = trustStorePassword == null ? null : trustStorePassword.toCharArray(); loadKeyStore(ts, passPhrase, trustStore); tmf.init(ts); return tmf; } public static void loadKeyStore(KeyStore ks, char[] passPhrase, String keyStoreFile) throws IOException, NoSuchAlgorithmException, CertificateException { try (InputStream in = new FileInputStream(keyStoreFile)) { ks.load(in, passPhrase); } }
TrustManagerFactory nesnesini yükleriz.
TrustManagerFactory trustManagerFactory = loadTrustManagerFactory( "password", " path to client1.truststore"), TrustManagerFactory.getDefaultAlgorithm(), "JKS");
Şöyle yaparız
// Create SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManager[] clientTrustManagers = trustManagerFactory.getTrustManagers(); sslContext.init(null, clientTrustManagers, new SecureRandom()); // Use SSLContext for building HttpClient HttpClient.Builder builder = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) .sslContext(sslContext) .connectTimeout(Duration.ofSeconds(20)) HttpClient httpClient = builder.build();
Örnek - Trust All Certificates
Elimizde şöyle bir kod olsun
// Create a trust manager that trusts all certificates. TrustManager [] trustAllCerts = new TrustManager [] {new X509ExtendedTrustManager () {
@Override public void checkClientTrusted (X509Certificate [] chain, String authType, Socket socket) { } @Override public void checkServerTrusted (X509Certificate [] chain, String authType, Socket socket) { } @Override public void checkClientTrusted (X509Certificate [] chain, String authType, SSLEngine engine) { } @Override public void checkServerTrusted (X509Certificate [] chain, String authType, SSLEngine engine) { } @Override public X509Certificate [] getAcceptedIssuers () { return null; } @Override
public void checkClientTrusted (X509Certificate [] c, String a) { } @Override
public void checkServerTrusted (X509Certificate [] c, String a) { } }};
Şöyle yaparız
public void testIgnoreSSL(String url) { // Create an SSL context and initialize it with the trust manager. SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new SecureRandom()); // Create an HTTP client and configure it to use the SSL context. HttpClient httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofMillis(10000)) .sslContext(sslContext) .build(); // Create a request and configure it to use the URL. HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .GET() .build(); // Send the request and print the response body. HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); }
disableHostnameVerification
Açıklaması şöyle
When you disable hostname verification, you are essentially telling the system to ignore the hostname in the server's SSL certificate when making a secure connection. This means that the client won't check whether the server's certificate matches the hostname it's trying to connect to.
Örnek - API İl Değiştirme
API ile değiştirme kodunu ilk defa burada gördüm. Daha sonra şöyle yaptım ama çalışmadı.
private HttpClient newClient() throws IOException {HttpClient.Builder builder = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1); if (sslEnabled) { SSLContext sslContext; try { sslContext = SSLContext.getInstance(tlsProtocol); } catch (NoSuchAlgorithmException e) { throw new IOException(e); } try { sslContext.init(clientKeyManagers, clientTrustManagers, new SecureRandom()); } catch (KeyManagementException e) { throw new IOException(e); } builder.sslContext(sslContext); // Disable host name verification in the certificate SSLParameters supportedSSLParameters = sslContext.getDefaultSSLParameters(); supportedSSLParameters.setEndpointIdentificationAlgorithm(null); builder.sslParameters(supportedSSLParameters); } // configure timeout on the entire client int timeout = 20; builder.connectTimeout(Duration.ofSeconds(timeout)); return builder .build(); }
Çünkü jdk/internal/net/http/AbstractAsyncSSLConnection.java sınıfında şu kod var ve System Property değerine bakarak benim verdiğim değeri eziyor
if (!disableHostnameVerification) sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
Örnek - System Property
Şöyle yaparız. Burada SSL sertifikası için yapılan host name verification etkisiz kılınıyor
System.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());HttpClient.Builder builder = HttpClient.newBuilder();SSLContext sslContext = ...;builder.sslContext(sslContext);HttpClient client = builder.build();HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();client.send(request, HttpResponse.BodyHandlers.ofString());
Hiç yorum yok:
Yorum Gönder