본문 바로가기

나의 플랫폼/안드로이드

[Android] Https Setting with Volley

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
아래 소스 같이 newSslSocketFactory 함수를 넣어서 추가 하면 됩니다.
인증서를 만드는 부분과 설정은 아래 내용을 참고 해주세요. 
public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HurlStack(null, newSslSocketFactory()));
        }
        return mRequestQueue;
    }

    ...

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = mCtx.getApplicationContext().getResources().openRawResource(R.raw.codeprojectssl);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Provide the password of the keystore
                trusted.load(in, KEYSTORE_PASSWORD);
            } finally {
                in.close();
            }

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(trusted);

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            SSLSocketFactory sf = context.getSocketFactory();
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }



defaulthttpclient 가 deprecated 되었다.... ㅠㅠ 아래 내용들은 쓸모가 없어 질듯 하다.



## 

https 포트를 사용하기 위해선, 그냥 도메인만 https로 바꾼다고 되는 것이 아니다.

ssl 인증을 받아야만 응답 처리가 가능하다.


그럼, 지금 부터 Https 포트를 이용해 보겠다.


이 글에선 전제 조건이 있다.

1. https 도메인이 지정되어 있다.

2. Public 키 파일을 가지고 있다.

3. 해당 키 파일에 비밀번호를 알고 있다.

4. Volley Library를 통하여 서버와 통신을 하고 있다.

5. java bin 폴더를 Path 지정 해놓은 상태이다.


참고 : 이 글을 쓸 때, 사용한 Volley 버전은 1.0.19 입니다. 

https://github.com/mcxiaoke/android-volley


자, 준비가 끝났으면 한번 만들어 보자.

Https를 사용하기위해선 인증 파일을 먼저 만들어야 한다.


[ 인증 파일 만들기 ]

우선, 아래 사이트를 들어가서 소스를 다운 받자.

https://github.com/moltak/android-https-volley


다운을 받아 압축을 풀면, convert_certification 폴더 안에 bcprov-jdk16-1.46.jar 파일이 있다.

이 폴더에 Public 키 파일을 복사해 넣는다.


cmd 명령창을 띄운 후, 해당 폴더로 이동한 다.

그리고, 아래 명령어를 실행 한다.

keytool -importcert -v -trustcacerts -file "Public 키 파일명" -alias imeto_alias -keystore "생성하고자 하는 키 파일명.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-1.46.jar" -storetype BKS


실행하고, 비밀번호를 입력한다. 비밀번호는 잘 외워두도록 하자.


그럼 '생성하고자 하는 키 파일' 이 생성된다. 이 파일을 우선 key.bks 라고 정하겠다.


참고 사이트 : http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/


[ 프로젝트에 인증 파일 적용 ]

안드로이드 프로젝트에 raw 폴더를 추가 시킨다.

해당 raw폴더 안에 인증 파일을 복사 시킨다.


다음 이전 사이트에서 받은 java 소스(com\https\app\SSL 폴더안에 모든 소스)를 전부 복사 해놓는다.

SslHttpClient 클래스로 이동 한 후, 아래 부분을 수정한다.


R.raw.certification -> R.raw.key

YOUR_PASS -> 인증 파일 비밀번호



마지막으로 Volley.newRequestQueuㄷ를 부를 때 아래와 같이 설정 하시면 됩니다.

Volley.newRequestQueue(context,new SslHttpStack(new SslHttpClient(context, 443)));


## 443은 HTTPS 포트 번호 입니다.



위와 같이 셋팅을 한 후, http 도메인을 https로 사용하시면 문제 없이 진행이 될 것 입니다.



마지막으로 SSL 인증 설정을 선택 합니다.

SslHttpClient 에 가면 setHostnameVerifier 함수의 매개변수 중 하나를 선택 하면 됩니다.

참고로,  setHostnameVerifier 함수는 apache 버전이 올라갈수록 쓸모가 없어 졌습니다. (deprecated됨)

따라서 크게 신경 쓰지 않으셔도 되겠습니다.



[ 참고 에러 ]

no peer certificate :

1. 포트번호를 맞게 하셨는지 제대로 확인이 필요

2. SslHttpClient 클래스에 인증 파일과 비밀번호를 제대로 인증 했는지 확인이 필요


HandShake Failed:

위 에러는 SSLv3 부분 제외 시켜야 한다고 한다. 서버에서 제외를 시키거나 Volley 라이브러리를 바꿔줘야 하는데,

이 글에서 사용한 소스를 이용하면 문제 없이 동작 되는 것을 확인 하였다.

하지만, 혹시 자료를 원하시는 분은 아래 사이트를 참고해도 나쁘지 않을 듯 하다.


http://stackoverflow.com/questions/22564317/https-support-for-volley-android-networking-library

https://github.com/Floens/Clover/commit/10c5c2b715ab76920891ecd275d9bf56767b2088



[ 추가 사항 ]

혹시 HttpEntity를 자체적으로 적용하시는 분들은 아래 부분을 수정 하시면 아마 잘 동작 될것이다.

SslHttpStack 클래스


 private HttpUriRequest createHttpRequest(Request<?> request, Map<String, String> additionalHeaders)

            throws AuthFailureError, UnsupportedEncodingException {

        switch (request.getMethod()) {

            case Request.Method.GET:

                return new HttpGet(request.getUrl());

            case Request.Method.POST:

                HttpPost post = new HttpPost(request.getUrl());

    post.setEntity(자신이 만든 Entity 추가);

                return post;

            default:

                throw new IllegalStateException("Unknown request method.");

        }

    }