ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • HTTPS 통신
    java 2019. 5. 2. 14:51

    인증 처리를 무시한체  접속하는 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");
    	}
    }
    

     

    인증서 파일 생성방법은 이곳을 참조 

    https://tjjava.blogspot.com/2012/03/https.html

    'java' 카테고리의 다른 글

    스트림  (0) 2019.05.21
    자바로 배우는 리팩토리 입문 0장  (0) 2019.05.12
    OS 메모리사용량, CPU사용량  (0) 2019.05.08
    스트림  (0) 2019.01.04
Designed by Tistory.