2

我需要建立Connectionwith 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 应用程序创建自签名证书。

4

2 回答 2

1

创建自签名证书不会解决您的问题,事实上,您连接的服务器正在使用自签名证书,这会导致您看到的错误。

您要么需要购买受信任的证书并将其安装在邮件服务器上(这可能超出您的控制范围),要么您需要更改 javamail 的行为以接受未经认可的权威机构签署的证书。

看看我对android javamail api imap over ssl的回答,它可以帮助您实现第二个选项。

于 2011-06-09T13:16:34.823 回答
1

未知证书的问题是 Java 中的一个已知问题。如果您的本地密钥库中没有正确的证书,您不能只连接到 HTTPS 服务器。

话虽如此,我在我的一个应用程序中有一个用于 Apache HTTP 客户端的覆盖子句(在 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;
        }
    }

}

祝你好运!

于 2011-06-09T13:14:19.950 回答