Yo mi aplicación que desea utilizar una conexión https a un usuario especificado por el servidor que utiliza un certificado auto-firmado. Lo que se ha reunido por ahora es, que

  • auto certificados firmados son rechazados (como se esperaba)
  • el android almacén de claves/almacén de confianza no se utiliza para las aplicaciones, por lo que las aplicaciones de la construcción y el uso de su propio almacén de confianza,
  • hay un «keytool» en el JDK para construir un almacén de confianza que puede ser suministrada a la aplicación como un recurso, que sin embargo no es una solución, ya que no sé el servidor (y su certificado de antemano)

Desde el servidor https es especificada por el usuario, no sé el certificado del servidor de antemano y por lo tanto queremos agregar el certificado de servidor mediante programación a la aplicación del almacén de confianza (mostrando el certificado para el usuario y tiene que aceptarlo). Una vez que se agrega al almacén de confianza, la aplicación deberá utilizar ese almacén de confianza para autenticar el servidor.

NO quiero simplemente aceptar todos los certificados auto-firmados sin que el usuario la comprobación de la huella digital como algunos ejemplos en la web sugieren.

Ahora el problema es que soy completamente nuevo en Java y Android y estoy luchando para entender el funcionamiento interno de la AndroidHttpClient o DefaultHttpClient. Tengo HTTP básicos de trabajo en mi aplicación, pero no he encontrado ningún ejemplo en cuanto a la forma de certificados de AGREGAR a un almacén de confianza dentro de la aplicación en la demanda del usuario.

¿Alguien sabe cómo lograr que o sabe un ejemplo de trabajo que puedo mirar?

Las sugerencias se agradece. Gracias.

EDIT: Encontré la Solución en el TrustManagerFactory.java clase de K9 Mail. Le sugiero que eche un vistazo a lo que si tienes la misma pregunta.

  • Sé que esta es una vieja cuestión, pero esto es justo lo que estoy buscando. Encontraste alguna solución?
  • Encontraste alguna Solución a este @nikmin
  • ¿Cómo se logró mediante el uso de TrustManagerFactory clase de k9 mail. como usted ha mencionado. Puede usted ayudarme por favor ?
InformationsquelleAutor machtnix | 2011-02-09

2 Comentarios

  1. 8

    Solución fue encontrada hace un tiempo, pero nadie ha creado la Respuesta sin embargo, para ayudar a guiar a los demás, así que voy a ser el Punto de Chulo(a) de esta mañana y post a la URL añadido como la solución, además de la copia en el código de la fuente pública. Espero que esto ayude a guiar a otros a la solución. 🙂


    Aquí está la URL para el código de abajo.

    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);
    }
    }
    }
    • el enlace no está activo ya
    • thx por la actualización. Buena cosa que copiar el código de ella antes de que desapareciera.
  2. -1

    Puede utilizar certificados autofirmados. El uso de un certificado auto-firmado, la puede convertir en castillo hinchable formato de almacén de claves que es compatible con Android y, a continuación, guárdelo como materia prima los recursos en su aplicación de Android de proyecto. Cómo convertir y uso, todos los detalles se pueden encontrar en el Bob el blog. Aquí está el enlace para la misma http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html. Esto funcionó bastante bien. Espero que esto ayude

    • Sólo puedo suponer que no lea la pregunta, específicamente la parte que dice «Desde el servidor https es especificada por el usuario, no sé el certificado del servidor de antemano y por lo tanto queremos agregar el certificado de servidor mediante programación a la aplicación del almacén de confianza»

Dejar respuesta

Please enter your comment!
Please enter your name here