android javamail api imap通过ssl [英] android javamail api imap over ssl

查看:205
本文介绍了android javamail api imap通过ssl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to get my Exchange emails on android and for that I am using javamail api for android... it works great on gmail and yahoo using imap. The problem is that my exchange server has self signed certificate so android don't like this too much and I get 03-14 12:46:13.698: WARN/System.err(281): javax.mail.MessagingException: Not trusted server certificate;

我看过以下示例:

I have seen this example: Sending Email in Android using JavaMail API without using the default/built-in app where somebody makes a send example over ssl.. I think I can use that JSSEProvider to accept my self signed certificate but I don't know how can I use it.

请帮助我!

推荐答案

我遇到了同样的问题,并且通过配置信任管理器来解决该问题,详情请参见

I have been having the same problem, and managed to get around it by configuring a trust manager as detailed at http://java.sun.com/products/javamail/javamail-1.4.2/SSLNOTES142.txt.

我所做的是创建自己的TrustManager:

What I did was create my own 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];
    }
}

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

and use this in my own 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();
    }
}

要使其在javamail-android中正常工作,您需要在获取Session实例之前指定新的SSLSocketFactory:

To get this to work in javamail-android, you need to specify the new SSLSocketFactory before you get a Session instance:

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

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

The TrustManager which we defined now be used instead of the default one, and all certificates will be accepted.

很明显,盲目接受所有证书存在一些安全问题,我建议您在TrustManager中进行一些检查,否则您可能会面临各种安全问题(例如中间人攻击) .另外,我只会在确实需要的地方使用此功能:例如,您说GMail和Ymail正常工作,因此在连接它们时我不会使用此机制.

Obviously there are some security issues with blindly accepting all certificates, and I would suggest doing some checking in your TrustManager, otherwise you could open yourself up to all kinds of security issues (such as man-in-the-middle attacks). Also, I would only use this where you really have to: for example you say that GMail and Ymail is working, so I would not use this mechanism when connecting to those.

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

I would put in an exception handler to catch the "Certificate not trusted" exception, and prompt the user to accept an untrusted certificate (with the necessary warning to only do this for servers that are absolutely trusted) before actually overriding the TrustManager.

这篇关于android javamail api imap通过ssl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆