2011-02-09 2 views
17

I 내 ​​앱 자체 서명 된 인증서를 사용하는 사용자 지정 서버에 https 연결을 사용하고 싶습니다. 내가프로그래밍 방식으로 인증서를 트러스트 스토어에 추가하고이를 서버 인증 확인에 사용하는 방법

  • 자체 서명 인증서 (예상대로) 응용 프로그램이 자신의 신뢰를 구축하고 사용 할 수 있도록
  • 안드로이드 스토어/트러스트 스토어,
  • , 응용 프로그램에 사용되지 거부되어, 지금에 의해 수집
  • 있기 때문에 그러나 나는 서버를 알 수 없기 때문에 해결책이 아닌 자원으로 응용 프로그램에 제공 할 수 있습니다 신뢰 (와 사전에 인증서)

를 구축 할 수있는 JDK에 "키 도구가"있다 https 서버가 사용자 지정, 나는 서버의 인증서 befo 모르겠어요 다시 작성하여 앱의 트러스트 스토어에 프로그래밍 방식으로 서버 인증서를 추가하려는 경우 (사용자에게 인증서를 보여주고 받아 들일 수 있도록) 일단 트러스트 스토어에 추가되면 앱은 해당 트러스트 스토어를 사용하여 서버를 인증해야합니다.

웹상의 몇 가지 예가 제시하는 것처럼 사용자가 지문을 확인하지 않고 모든 자체 서명 인증서를 수락하는 것을 원하지 않습니다.

이제는 Java와 Android에 완전히 익숙하지 않아 AndroidHttpClient 또는 DefaultHttpClient의 내부 동작을 이해하는 데 어려움을 겪고 있습니다. 나는 기본적인 HTTP가 내 애플 리케이션에서 일하고 있지만 실제로 사용자의 요구에 따라 앱 내부의 트러스트 스토어에 인증서를 실제로 추가하는 방법에 대한 예제를 발견하지 못했다.

누구나 그 방법을 알고 있거나 내가 볼 수있는 작동 예제를 알고 있습니까?

힌트를 보내 주시면 감사하겠습니다. 감사.

편집 : TrustManagerFactory.java class of K9 Mail에서 솔루션을 찾았습니다. 나는 당신이 동일한 질문을하는 경우에 그것을 보는 것이 좋습니다.

+2

나는 이것이 오래된 질문이라는 것을 알고 있지만 이것은 내가 찾고있는 것입니다. 해결책을 찾았습니까? – nikmin

+0

이 @nikmin에 대한 해결책을 찾았습니까 –

+0

@machtnix : 어떻게 TrustManagerFactory 클래스의 k9 메일을 사용하여 달성 했습니까? 당신이 말했듯이. 저를 도와주세요 ? –

답변

-1

자체 서명 인증서를 사용할 수 있습니다. 자체 서명 된 인증서를 사용하려면 Android에서 지원되는 탄력성있는 형식의 키 저장소로 변환 한 다음 Android 애플리케이션 프로젝트에 원시 리소스로 저장합니다. 그것을 변환하고 사용하는 방법, 모든 세부 사항은 Bob의 블로그에서 찾을 수 있습니다. 여기에 같은 링크가 있습니다 - http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html. 이것은 꽤 잘 돌아갔다. 희망이 있습니다

+5

"https 서버가 사용자 지정이므로 서버의 인증서를 미리 모르기 때문에 프로그래밍 방식으로 서버의 인증서를 응용 프로그램의 트러스트 스토어에 추가하려고합니다."라는 질문을 읽지 않았다고 가정 할 수 있습니다. – Fuzzy

8

해결책이 조금 전에 발견되었지만 누구도 아직 다른 사람들을 안내하는 데 도움이되지 못했기 때문에 오늘 아침에 Point Pimp (ette)가되어 솔루션으로 추가 된 URL을 게시하고 복사하십시오 공개 소스 코드에서. 희망은 이것이 다른 사람들을 해결책으로 인도하는 데 도움이되기를 바랍니다. :)


Here's the URL 아래 코드를 참조하십시오.

package com.fsck.k9.mail.store; 

import android.app.Application; 
import android.content.Context; 
import android.util.Log; 
import com.fsck.k9.K9; 
import com.fsck.k9.helper.DomainNameChecker; 
import org.apache.commons.io.IOUtils; 

import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 
import java.util.HashMap; 
import java.util.Map; 

public final class TrustManagerFactory { 
    private static final String LOG_TAG = "TrustManagerFactory"; 

    private static X509TrustManager defaultTrustManager; 
    private static X509TrustManager unsecureTrustManager; 
    private static X509TrustManager localTrustManager; 

    private static X509Certificate[] lastCertChain = null; 

    private static File keyStoreFile; 
    private static KeyStore keyStore; 


    private static class SimpleX509TrustManager implements X509TrustManager { 
     public void checkClientTrusted(X509Certificate[] chain, String authType) 
     throws CertificateException { 
     } 

     public void checkServerTrusted(X509Certificate[] chain, String authType) 
     throws CertificateException { 
     } 

     public X509Certificate[] getAcceptedIssuers() { 
      return null; 
     } 
    } 

    private static class SecureX509TrustManager implements X509TrustManager { 
     private static final Map<String, SecureX509TrustManager> mTrustManager = 
      new HashMap<String, SecureX509TrustManager>(); 

     private final String mHost; 

     private SecureX509TrustManager(String host) { 
      mHost = host; 
     } 

     public synchronized static X509TrustManager getInstance(String host) { 
      SecureX509TrustManager trustManager; 
      if (mTrustManager.containsKey(host)) { 
       trustManager = mTrustManager.get(host); 
      } else { 
       trustManager = new SecureX509TrustManager(host); 
       mTrustManager.put(host, trustManager); 
      } 

      return trustManager; 
     } 

     public void checkClientTrusted(X509Certificate[] chain, String authType) 
     throws CertificateException { 
      defaultTrustManager.checkClientTrusted(chain, authType); 
     } 

     public void checkServerTrusted(X509Certificate[] chain, String authType) 
     throws CertificateException { 
      // FIXME: Using a static field to store the certificate chain is a bad idea. Instead 
      // create a CertificateException subclass and store the chain there. 
      TrustManagerFactory.setLastCertChain(chain); 
      try { 
       defaultTrustManager.checkServerTrusted(chain, authType); 
      } catch (CertificateException e) { 
       localTrustManager.checkServerTrusted(new X509Certificate[] {chain[0]}, authType); 
      } 
      if (!DomainNameChecker.match(chain[0], mHost)) { 
       try { 
        String dn = chain[0].getSubjectDN().toString(); 
        if ((dn != null) && (dn.equalsIgnoreCase(keyStore.getCertificateAlias(chain[0])))) { 
         return; 
        } 
       } catch (KeyStoreException e) { 
        throw new CertificateException("Certificate cannot be verified; KeyStore Exception: " + e); 
       } 
       throw new CertificateException("Certificate domain name does not match " 
               + mHost); 
      } 
     } 

     public X509Certificate[] getAcceptedIssuers() { 
      return defaultTrustManager.getAcceptedIssuers(); 
     } 

    } 

    static { 
     java.io.InputStream fis = null; 
     try { 
      javax.net.ssl.TrustManagerFactory tmf = javax.net.ssl.TrustManagerFactory.getInstance("X509"); 
      Application app = K9.app; 
      keyStoreFile = new File(app.getDir("KeyStore", Context.MODE_PRIVATE) + File.separator + "KeyStore.bks"); 
      keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      try { 
       fis = new java.io.FileInputStream(keyStoreFile); 
      } catch (FileNotFoundException e1) { 
       fis = null; 
      } 
      try { 
       keyStore.load(fis, "".toCharArray()); 
      } catch (IOException e) { 
       Log.e(LOG_TAG, "KeyStore IOException while initializing TrustManagerFactory ", e); 
       keyStore = null; 
      } catch (CertificateException e) { 
       Log.e(LOG_TAG, "KeyStore CertificateException while initializing TrustManagerFactory ", e); 
       keyStore = null; 
      } 
      tmf.init(keyStore); 
      TrustManager[] tms = tmf.getTrustManagers(); 
      if (tms != null) { 
       for (TrustManager tm : tms) { 
        if (tm instanceof X509TrustManager) { 
         localTrustManager = (X509TrustManager)tm; 
         break; 
        } 
       } 
      } 
      tmf = javax.net.ssl.TrustManagerFactory.getInstance("X509"); 
      tmf.init((KeyStore)null); 
      tms = tmf.getTrustManagers(); 
      if (tms != null) { 
       for (TrustManager tm : tms) { 
        if (tm instanceof X509TrustManager) { 
         defaultTrustManager = (X509TrustManager) tm; 
         break; 
        } 
       } 
      } 

     } catch (NoSuchAlgorithmException e) { 
      Log.e(LOG_TAG, "Unable to get X509 Trust Manager ", e); 
     } catch (KeyStoreException e) { 
      Log.e(LOG_TAG, "Key Store exception while initializing TrustManagerFactory ", e); 
     } finally { 
      IOUtils.closeQuietly(fis); 
     } 
     unsecureTrustManager = new SimpleX509TrustManager(); 
    } 

    private TrustManagerFactory() { 
    } 

    public static X509TrustManager get(String host, boolean secure) { 
     return secure ? SecureX509TrustManager.getInstance(host) : 
       unsecureTrustManager; 
    } 

    public static KeyStore getKeyStore() { 
     return keyStore; 
    } 

    public static void setLastCertChain(X509Certificate[] chain) { 
     lastCertChain = chain; 
    } 
    public static X509Certificate[] getLastCertChain() { 
     return lastCertChain; 
    } 

    public static void addCertificateChain(String alias, X509Certificate[] chain) throws CertificateException { 
     try { 
      javax.net.ssl.TrustManagerFactory tmf = javax.net.ssl.TrustManagerFactory.getInstance("X509"); 
      for (X509Certificate element : chain) { 
       keyStore.setCertificateEntry 
       (element.getSubjectDN().toString(), element); 
      } 

      tmf.init(keyStore); 
      TrustManager[] tms = tmf.getTrustManagers(); 
      if (tms != null) { 
       for (TrustManager tm : tms) { 
        if (tm instanceof X509TrustManager) { 
         localTrustManager = (X509TrustManager) tm; 
         break; 
        } 
       } 
      } 
      java.io.OutputStream keyStoreStream = null; 
      try { 
       keyStoreStream = new java.io.FileOutputStream(keyStoreFile); 
       keyStore.store(keyStoreStream, "".toCharArray()); 
      } catch (FileNotFoundException e) { 
       throw new CertificateException("Unable to write KeyStore: " + e.getMessage()); 
      } catch (CertificateException e) { 
       throw new CertificateException("Unable to write KeyStore: " + e.getMessage()); 
      } catch (IOException e) { 
       throw new CertificateException("Unable to write KeyStore: " + e.getMessage()); 
      } finally { 
       IOUtils.closeQuietly(keyStoreStream); 
      } 

     } catch (NoSuchAlgorithmException e) { 
      Log.e(LOG_TAG, "Unable to get X509 Trust Manager ", e); 
     } catch (KeyStoreException e) { 
      Log.e(LOG_TAG, "Key Store exception while initializing TrustManagerFactory ", e); 
     } 
    } 
} 
+1

링크가 더 이상 작동하지 않습니다. – Bhargav

+1

@Bhargav thx가 업데이트되었습니다.코드가 사라지기 전에 코드를 복사 한 것이 좋습니다. – Lizz