我一直有同样的问题,并设法通过配置信任管理器来解决它,详见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];
}
}
,并使用这在我自己的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的工作在获得会话实例之前新的SSLSocketFactory:
Properties props = new Properties();
props.setProperty("mail.imaps.socketFactory.class", "com.myapp.DummySSLSocketFactory");
session = Session.getDefaultInstance(props);
我们现在定义的TrustManager被使用而不是默认的,并且所有的证书都会被接受。
很明显,有一些安全问题会盲目地接受所有证书,我建议在TrustManager中进行一些检查,否则您可能会面临各种安全问题(如中间人攻击(man-in-the-middle attacks) )。另外,我只会在你真正需要的地方使用它:例如你说GMail和Ymail正在工作,所以在连接到这些机制时我不会使用这种机制。
我会在异常处理程序中捕获“证书不可信”异常,并提示用户在实际覆盖之前接受不受信任的证书(必须警告只对完全信任的服务器执行此操作)的TrustManager。
它正在工作perfeclty!非常感谢! – Merve 2012-05-28 08:49:07
千万不要这样做。它信任每个证书,您可以完全禁用SSL。攻击者在这里有一个非常容易的工作。绝对有可能只向信任存储添加一组定义的可信证书,并且可以询问用户是否要接受证书。 正如你对此提醒的那样,我已经收回了我的失望。 – 2014-03-14 17:23:29