-
인증 처리를 무시한체 접속하는 HTTPS 통신
package com.test.https.practice; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; //인증 없이 서버접속 public class HttpsClientWithoutValidation { public void getHttps(String urlString) throws IOException, NoSuchAlgorithmException, KeyManagementException{ //get Https urlconnection URL url = new URL(urlString); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); //호스트 이름 검증 설정 conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { //무시한다 호스트네임 검증을 항상 트루를 반환 return true; } }); //SSL셋팅 SSLContext context = SSLContext.getInstance("TLS"); context.init(null, null, null); conn.setSSLSocketFactory(context.getSocketFactory()); //Connect to host conn.connect(); conn.setInstanceFollowRedirects(true); //Print response from host InputStream in = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line =null; while((line = br.readLine())!= null){ System.out.printf("%s\n",line); } br.close(); } public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException { HttpsClientWithoutValidation test = new HttpsClientWithoutValidation(); test.getHttps("https://www.google.com"); } }
공인인증된 인증서로 서버인증
SSLContext.init() 함수의 두번째 인자에 X509TrustManager 를 선언하여 집어 넣었다.
그리고 JRE 를 설치하면 기본적으로 [JRE 경로]/lib/security/cacerts 라는 파일명의 공인 인증된 인증서 저장소 파일이 있다.
해당 인증서 저장소를 이용하여 서버의 인증서를 검사하게 하였다.package com.test.https.practice; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; //공인 인증된 인증서로 서버 인증 public class HttpsClientWithDefaultCACert { public void getHttps(String urlString) throws IOException, NoSuchAlgorithmException, KeyManagementException{ //get https URL connection URL url = new URL(urlString); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); //호스트 이름 검증 설정 conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { //호스트 이름 검증을 무신한다. 항상 트루를 반환 return true; } }); //SSL settig SSLContext context = SSLContext.getInstance("TLS"); context.init(null,new TrustManager[] {new X509TrustManager(){ @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { //클라이언트 인증 체크 } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { //서버 인증 체크 try { //get trust store KeyStore trustStore = KeyStore.getInstance("JKS"); String cacertPath = System.getProperty("java.home")+"/lib/security/cacerts"; //Trust store path should be diffrent by system plaform. trustStore.load(new FileInputStream(cacertPath), "changeit".toCharArray()); //Use Default certification validation //get Trust Manager TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); TrustManager[] tms = tmf.getTrustManagers(); ((X509TrustManager)tms[0]).checkServerTrusted(chain, authType); } catch (KeyStoreException e) { e.printStackTrace(); }catch (NoSuchAlgorithmException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }, null); //Connect to host conn.connect(); conn.setInstanceFollowRedirects(true); //Prinst response from host InputStream in = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; while((line = br.readLine()) != null){ System.out.printf("%s\n",line); } br.close(); } public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException { HttpsClientWithDefaultCACert test = new HttpsClientWithDefaultCACert(); test.getHttps("https://www.google.com"); } }
서버는 지정된 인증키 저장소를 이용해 클라이언트에 자신을 인증하는 키를 보내게 됨.
인증과정이 성공하면 클라이언트에게 html 내용물을 전달하고 종료
package com.test.https.practice; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocket; import javax.swing.KeyStroke; //사용자가 만든 인증키를 이용하는 간단한 HTTPS 서버 //keystore.jks - 서버(SimpleHttpsServer) 에서 사용하는 인증키 저장소 //ruststore.jks - 클라이언트(HttpsClientWithCustomCert) 에서 서버 인증시 사용하는 인증서 저장소 public class SimpleHttpsServer { public void run(int port) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException{ //create ssl context SSLContext context = SSLContext.getInstance("TLS"); //set keystore KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(new FileInputStream("keystore.jks"), "jks파일생성시 입력한 패스워드".toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, "kjh48001".toCharArray()); context.init(kmf.getKeyManagers(), null, null); //creat ssl socket SSLServerSocketFactory factory = context.getServerSocketFactory(); SSLServerSocket socket = (SSLServerSocket)factory.createServerSocket(port); SSLSocket client = (SSLSocket) socket.accept(); InputStream in = client.getInputStream(); OutputStream out = client.getOutputStream(); //read from client BufferedReader br = new BufferedReader(new InputStreamReader(in)); br.readLine(); //write to client BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write("HTTP/1.0 200 OK"); writer.newLine(); writer.write("Content-Type: text/html"); writer.newLine(); writer.newLine(); writer.write("<html><head><title>hello https</title></head><body>Hello HTTPS<body></html>"); writer.flush(); //close writer.close(); br.close(); client.close(); } public static void main(String[] args) throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException { SimpleHttpsServer server = new SimpleHttpsServer(); server.run(8080); } }
클라이언트는 지정된 인증저장소를 이용해 서버를 인증한다.
인증과정이 성공하면 html내용물을 전달 받는다.
package com.test.https.practice; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; //사용자가 만든 인증서를 이용하여 서버인증 public class HttpsClientWithCustomCert { public void getHttps(String urlString) throws IOException, NoSuchAlgorithmException, KeyManagementException{ //get Https URL connection URL url = new URL(urlString); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); //Set HostName verification conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { //호스트 이름 검증은 무시 항상 true를 반환 return true; } }); //SSL setting SSLContext context = SSLContext.getInstance("TLS"); context.init(null,new TrustManager [] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { //서버 인증 체크 try { //get turst store KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(new FileInputStream("truststore.jks"), "jks생성시 입력한 인증서 비밀번호 ".toCharArray()); // getTrust Manager TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); TrustManager[] tms = tmf.getTrustManagers(); ((X509TrustManager)tms[0]).checkServerTrusted(chain, authType); } catch (KeyStoreException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // 클라이언트 인증 체크 } } }, null); conn.setSSLSocketFactory(context.getSocketFactory()); //Connect to host conn.connect(); conn.setInstanceFollowRedirects(true); //Print response from host InputStream in = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; while((line = br.readLine())!=null){ System.out.printf("%s/n", line); } br.close(); } public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException { HttpsClientWithCustomCert test = new HttpsClientWithCustomCert(); test.getHttps("https://127.0.0.1:8080"); } }
인증서 파일 생성방법은 이곳을 참조
'java' 카테고리의 다른 글
스트림 (0) 2019.05.21 자바로 배우는 리팩토리 입문 0장 (0) 2019.05.12 OS 메모리사용량, CPU사용량 (0) 2019.05.08 스트림 (0) 2019.01.04