sssl上的android javamail api imap

Cat*_*ata 1 android imap jakarta-mail ssl-certificate

我想在Android上获取我的Exchange电子邮件,为此我使用javamail api for android ...它在使用imap的gmail和yahoo上工作得很好.问题是我的交换服务器有自签名证书所以android不太喜欢这个,我得到了03-14 12:46:13.698: WARN/System.err(281): javax.mail.MessagingException: Not trusted server certificate;

我已经看到了这个例子:使用JavaMail API在Android中发送电子邮件而不使用默认/内置应用程序,其中有人通过ssl发送示例..我想我可以使用JSSEProvider接受我的自签名证书但我不知道我知道如何使用它.

请帮我!

Mar*_*son 7

我遇到了同样的问题,并设法通过配置信任管理器来解决这个问题,详见http://java.sun.com/products/javamail/javamail-1.4.2/SSLNOTES142.txt.

我做的是创建自己的TrustManager:

package com.myapp;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

/**
 * DummyTrustManager - NOT SECURE
 */
public class DummyTrustManager implements X509TrustManager {

    public void checkClientTrusted(X509Certificate[] cert, String authType) {
    // everything is trusted
    }

    public void checkServerTrusted(X509Certificate[] cert, String authType) {
    // everything is trusted
    }

    public X509Certificate[] getAcceptedIssuers() {
    return new X509Certificate[0];
    }
}
Run Code Online (Sandbox Code Playgroud)

并在我自己的SSLSocketFactory中使用它:

package com.myapp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.net.ssl.*;


/**
 * DummySSLSocketFactory
 */
public class DummySSLSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory factory;

    public DummySSLSocketFactory() {
    try {
        SSLContext sslcontext = SSLContext.getInstance("TLS");
        sslcontext.init(null,
                 new TrustManager[] { new DummyTrustManager()},
                 null);
        factory = (SSLSocketFactory)sslcontext.getSocketFactory();
    } catch(Exception ex) {
        // ignore
    }
    }

    public static SocketFactory getDefault() {
    return new DummySSLSocketFactory();
    }

    public Socket createSocket() throws IOException {
    return factory.createSocket();
    }

        public Socket createSocket(Socket socket, String s, int i, boolean flag)
                throws IOException {
    return factory.createSocket(socket, s, i, flag);
    }

    public Socket createSocket(InetAddress inaddr, int i,
                InetAddress inaddr1, int j) throws IOException {
    return factory.createSocket(inaddr, i, inaddr1, j);
    }

    public Socket createSocket(InetAddress inaddr, int i)
                throws IOException {
    return factory.createSocket(inaddr, i);
    }

    public Socket createSocket(String s, int i, InetAddress inaddr, int j)
                throws IOException {
    return factory.createSocket(s, i, inaddr, j);
    }

    public Socket createSocket(String s, int i) throws IOException {
    return factory.createSocket(s, i);
    }

    public String[] getDefaultCipherSuites() {
    return factory.getDefaultCipherSuites();
    }

    public String[] getSupportedCipherSuites() {
    return factory.getSupportedCipherSuites();
    }
}
Run Code Online (Sandbox Code Playgroud)

为了得到这个JavaMail的,Android的工作,你需要你得到一个会话实例之前指定新的SSLSocketFactory:

    Properties props = new Properties();
    props.setProperty( "mail.imaps.socketFactory.class", "com.myapp.DummySSLSocketFactory" );
    session = Session.getDefaultInstance( props );
Run Code Online (Sandbox Code Playgroud)

我们现在定义的TrustManager使用而不是默认的TrustManager,并且将接受所有证书.

显然,盲目接受所有证书存在一些安全问题,我建议您在TrustManager中进行一些检查,否则您可能会遇到各种安全问题(例如中间人攻击).另外,我只会在你真正需要的地方使用它:例如你说GMail和Ymail正在工作,所以在连接到那些时我不会使用这种机制.

我会放入一个异常处理程序来捕获"不受信任的证书"异常,并提示用户在实际覆盖TrustManager之前接受不受信任的证书(带有必要的警告,仅对绝对可信的服务器执行此操作).