Как я могу подключиться к почтовому серверу, используя IMAP через SSL в Android? - PullRequest
2 голосов
/ 09 июня 2011

Мне нужно установить Connection с MailServer (сервер настраиваемой почты).Всякий раз, когда я пытался подключиться, выдается исключение javax.net.SSLException, Not trusted server certificate.

Я не знаю, как создать сертификат для этого.А также не знаю, чтобы передать этот сертификат, чтобы установить безопасное соединение с почтовым сервером.

Мой код:

Properties props;// = new Properties();
            Session session;

            props=new Properties();

            props.put("mail.imap.socketFactory.port", "993");   
            props.put("mail.imap.socketFactory.class",   
                    "javx.net.ssl.SSLSocketFactory");   
            session=Session.getDefaultInstance(props, null);
            Store store = session.getStore("imaps");
            store.connect(hostName,portNumber, emailId,password);
            //the above statement throws the Exception    
            Folder folder = store.getFolder("INBOX");

Я хотел бы знать, как создать самозаверяющий сертификат для приложения Android.

Ответы [ 2 ]

1 голос
/ 09 июня 2011

Создание самозаверяющего сертификата не решит вашу проблему, это факт, что сервер, к которому вы подключаетесь, использует самозаверяющий сертификат, который вызывает ошибку, которую вы видите.

Вам необходимо либо купить доверенный сертификат и установить его на почтовом сервере (который может быть вне вашего контроля), либо изменить поведение javamail для приема сертификатов, которые не подписаны признанным органом.

Посмотрите на мой ответ на Android javamail api imap поверх ssl , который может помочь вам реализовать второй вариант.

1 голос
/ 09 июня 2011

Проблема с неизвестными сертификатами - это известная проблема в Java. Вы не можете просто подключиться к HTTPS-серверу без правильного сертификата в вашем локальном хранилище ключей.

Как уже говорилось, в одном из моих приложений есть пункт переопределения для Apache HTTP Client (то же самое, что используется в Android), вы можете начать с него и использовать его для запуска на Android

ClientConnectionManager cm = new SingleClientConnManager(params,     
    HttpsSecurityOverride.createAllowAllSchemeRegistry());
httpClient = new DefaultHttpClient(cm, params);

и класс HttpsSecurityOverride выглядит следующим образом:

package net.milanaleksic.cuc.tools.async.http;

import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.*;

import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.X509HostnameVerifier;

public class HttpsSecurityOverride {

    private static SchemeRegistry allowAllSchemeRegistry = null;

    private static class AllowAllTrustManager implements X509TrustManager {

        @Override public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }

        @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {
        }

        @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {
        }
    }

    private static class AllowAllHostnameVerifier implements X509HostnameVerifier {

        @Override public void verify(String arg0, SSLSocket arg1) throws IOException {
        }

        @Override public void verify(String arg0, X509Certificate arg1) throws SSLException {
        }

        @Override public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {
        }

        @Override public boolean verify(String arg0, SSLSession arg1) {
            return true;
        }

    }

    public static SchemeRegistry createAllowAllSchemeRegistry() throws Exception {
        synchronized (HttpsSecurityOverride.class) {
            if (allowAllSchemeRegistry != null)
                return allowAllSchemeRegistry;

            SSLContext sslContext = SSLContext.getInstance("SSL");

            // set up a TrustManager that trusts everything
            sslContext.init(null, new TrustManager[] { new AllowAllTrustManager() }, new SecureRandom());

            org.apache.http.conn.ssl.SSLSocketFactory sf = new org.apache.http.conn.ssl.SSLSocketFactory(sslContext);
            sf.setHostnameVerifier(new AllowAllHostnameVerifier());
            Scheme httpsScheme = new Scheme("https", sf, 443);
            allowAllSchemeRegistry = new SchemeRegistry();
            allowAllSchemeRegistry.register(httpsScheme);

            return allowAllSchemeRegistry;
        }
    }

}

Удачи!

...