У меня возникла та же проблема, и мне удалось ее обойти, настроив диспетчер доверия, как описано в 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, прежде чем вы получите экземпляр Session:
Properties props = new Properties();
props.setProperty( "mail.imaps.socketFactory.class", "com.myapp.DummySSLSocketFactory" );
session = Session.getDefaultInstance( props );
TrustManager, который мы определили сейчас, будет использоваться вместо стандартного, и все сертификаты будут приняты.
Очевидно, что при слепом приеме всех сертификатов существуют некоторые проблемы безопасности, и я бы посоветовал провести некоторую проверку в вашемTrustManager, в противном случае вы можете столкнуться с любыми проблемами безопасности (например, атаками «человек посередине»).Кроме того, я бы использовал это только там, где вам действительно нужно: например, вы говорите, что GMail и Ymail работают, поэтому я не буду использовать этот механизм при подключении к ним.
Я бы добавил обработчик исключений дляперехватите исключение «Сертификат не является доверенным» и предложите пользователю принять ненадежный сертификат (с необходимым предупреждением, чтобы сделать это только для абсолютно доверенных серверов), прежде чем фактически переопределить TrustManager.