728x90

과정은 인증서를 설정해주는 것 외에는 보통의 hHttpURLConnection을 이요한 통신과 흡사하다.


private HttpsURLConnection urlConnection;
    private String method;
    private SSLContext sslContext;

    public static int BUFFER_SIZE = 1024;

    public HttpsURLConnection getConnection(Context context, String url, String requestMethod) {
        try {
            setCertification(context);

            // URL 설정
            URL request_url = new URL(url);
            method = requestMethod;

            urlConnection = (HttpsURLConnection) request_url.openConnection();
            urlConnection.setRequestMethod(method);
            urlConnection.setReadTimeout(95 * 1000);
            urlConnection.setConnectTimeout(95 * 1000);
            urlConnection.setDoInput(true);

            if (requestMethod.equals("GET"))
            {
                urlConnection.setRequestProperty("Accept", "application/json");
                urlConnection.setRequestProperty("X-Environment", "android");
            } else {
                urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                urlConnection.setRequestProperty("X-Environment", "android");
            }

            urlConnection.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            // 위에서 설정한 인증서 사용
            urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

            urlConnection.connect();

        } catch(ConnectException ce) {
            // 커넥션 오류
            ce.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return urlConnection;
    }

주의점은 HttpURLConnection이 아닌 HttpsURLConnection이다. 's'가 붙어있다.


메소드는 HttpURLConnection을 상속하고 있어서 비슷하다.


private void setCertification(Context context) throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = context.getResources().openRawResource(R.raw.nive_crt); 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 = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); }

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


구글 문서에서 제공하는 코드이다. 인증서 데이터는 /res/raw/ 에 두고 openRawResource()메소드로 가져오고 있다.


    public String request(String content) {
        try {
            if(method.equals("POST")) {
                // POST 일때만 실행
                OutputStream outputStream = urlConnection.getOutputStream();
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                bufferedWriter.write(content);
                bufferedWriter.flush();
                bufferedWriter.close();
                outputStream.close();
            }

            String response = null;
            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                response = readStream();
            }

            urlConnection.disconnect();

            return response;
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    private String readStream() throws Exception {
        StringBuilder responseStringBuilder = new StringBuilder();

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        for (; ; ) {
            String stringLine = bufferedReader.readLine();
            if (stringLine == null) break;
            responseStringBuilder.append(stringLine + '\n');
        }
        bufferedReader.close();

        return responseStringBuilder.toString();
    }

    public void disconnect() {
        urlConnection.disconnect();
    }

요청, 응답 코드


728x90

+ Recent posts