2016-08-10 1 views
1

HTTPS TLS 연결을위한 공개 키 고정. X509TrustManagerExtensions를 통한 공개 키 고정 checkServer 신뢰 된

공개 키 고정을 사용하여 MITM (Man in the Middle) 공격을 허용하는 17 세 미만의 Android API에 문제가 있습니다. 이것은 아래의 링크에서 설명되었습니다.

그래서 안드로이드 버전 4.2 이하 17 이하 안드로이드 최소 SDK, 즉,에, 우리는 서버 루트 인증서 (대신 기본 키 스토어의 이있는 안드로이드 키 스토어로 X509TrustManager의를 초기화 할 필요가; 장치에 설치된 모든 인증서가있는). 이렇게하면 공개 키 고정을 수행하기 전에 서버에서받은 리프 인증서를 정리하는 데 도움이됩니다.

Android API 17 이상부터 Android는 OS 레벨에서이 루트 정리를 수행하는 X509TrustManagerExtensions을 도입했습니다.

https://developer.android.com/reference/android/net/http/X509TrustManagerExtensions.html

내 질문 :

사람이 루트 청소에 대한 X509TrustManagerExtensions에서 제공하는 다음의 방법을 구현하는 방법에 대한 예를 제공하시기 바랍니다 수 있다면 다행 일 것이다.

List<X509Certificate> checkServerTrusted (X509Certificate[] chain, 
       String authType, 
       String host) 

다음과 혼동 스럽습니다.

  1. ; 도메인 URL이어야합니까? https와 함께 또는없이? 또는 전체 URL (도메인 + 상대 경로)이어야합니까

  2. X509TrustManagerExtensions의 인스턴트를 만드는 방법은 무엇입니까? X509TrustManagerExtensions의 생성자는 X509TrustManager을 입력으로 사용합니다. 안드로이드 기본 키 저장소로이 X509TrustManager를 생성합니까?

코드 (작동하지 않음) :

TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); 
    tmf.init(KeyStore.getInstance(KeyStore.getDefaultType())); 

    for (TrustManager trustManager : tmf.getTrustManagers()) { 
     X509TrustManagerExtensions tme = new X509TrustManagerExtensions((X509TrustManager) trustManager); 
     tme.checkServerTrusted(chain, authType, <<String https://www.example.com>>); 
    } 

예외 :

가능한 보안 위험이 발견되지 인증 경로에 대한 신뢰 앵커 : 사용 KeyStore.getDefaultType()

도움을 주시면 대단히 감사하겠습니다.

+0

> = API 17을 사용할 수없는 이유가 있습니까? – Chris

+0

'X509TrustManagerExtensions'는 API 17 이상에서만 제공됩니다. –

답변

1

먼저 TrustManagerFactory을 사용하여 트러스트 관리자를 확보해야합니다. 이것을 초기화 할 때 기본값 인 Keystore을 사용하기 위해 null을 전달하면 기본 신뢰 관리자가 반환됩니다. 이렇게하면 을 사용하여 X509TrustManagerExtensions을 만들 수 있습니다.

Certificate[] serverCerts = ((HttpsUrlConnection)conn).getServerCertificates(); 
X509Certificate[] untrustedCerts = Arrays.copyOf(serverCerts, 
     serverCerts.length, 
     X509Certificate[].class); 

경우 :로 결정되는 신뢰할 수없는 인증서 표시를 HttpUrlConnection를 사용하는 사람들을 위해

List<X509Certificate> trustedCerts = x509TrustManagerExtensions 
     .checkServerTrusted(untrustedCerts, "RSA", "appmattus.com"); 

: 다음

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
     TrustManagerFactory.getDefaultAlgorithm()); 
trustManagerFactory.init((KeyStore) null); 

// Find first X509TrustManager in the TrustManagerFactory 
X509TrustManager x509TrustManager = null; 
for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { 
    if (trustManager instanceof X509TrustManager) { 
     x509TrustManager = (X509TrustManager) trustManager; 
     break; 
    } 
} 

X509TrustManagerExtensions x509TrustManagerExtensions = 
     new X509TrustManagerExtensions(trustManager()); 

내가 성공적으로 바로 도메인 부분을 사용했습니다이 호스트를 실행합니다 당신은 OkHttp를 사용하고 있습니다. 그런 다음이 기사에서 언급 된 문제를 수정하기 위해 업데이트 된 CertificatePinner에 내장 된 것을 사용할 수 있습니다.