본문 바로가기
2023년 이전/Android

Android 에서 https 사용하여 접속하기

by JeongUPark 2019. 12. 3.
반응형

이전에 https와 openssl을 사용하여 https 서버를 만들어 보았습니다.(서버 만드는 내용은 여기서 확인하실 수 있습니다.)

 

그럼 이번에는 client인 android 에서 https로 요청을 보내보도록 하겠습니다.

 

방법은 http 요청 방식을 https 바꾸는데 공개키를 추가하여 전달하면 됩니다. (android developer를 참고하였습니다.)

 

    // Load CAs from an InputStream
    // (could be from a resource or ByteArrayInputStream or ...)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
	AssetManager am = context.getResources().getAssets() ;
	InputStream caInput = am.open("cert.pem");
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }

    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);

    // Tell the URLConnection to use a SocketFactory from our SSLContext
    URL url = new URL([요청 url]);
    HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    InputStream in = urlConnection.getInputStream();
    copyInputStreamToOutputStream(in, System.out);
    

 

SSL을 등록하는 방법입니다. 저 같은 경우에는 asset에 공개키를 저장하고 그 키를 불러왔습니다.

 

하지만 이 방식을 취해서 client에서 REST api 방식을 데이터를 요청하면 

 

javax.net.ssl.SSLPeerUnverifiedException: Hostname [입력 url] not verified: 0 

exception이 발생합니다.

 

그 이유는 웹일 경우 ca가 아닌 인증서를 사용하는 도메인에 접속할 경우 나타나는 

 

이런 상황 처럼 android client에서도 인증을 검증 해주어야 합니다.

 

그래서 connect 전에

 

urlConnection.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true; //default가 false 입니다.
    }
});

을 추가하여 handshaking동안 검증 메커니즘은이 인터페이스의 구현 자에게 콜백하여이 연결이 허용되는지 여부를 판별 할 수 있도록 합니다.

 

그럼 정상 적으로 https 통신이 되는 것을 확인 할 수 있습니다.

 

 

참고

https://developer.android.com/training/articles/security-ssl?hl=ko

반응형