连接到APN时SSLHandshake异常

时间:2016-02-05 02:06:10

标签: java https apple-push-notifications

我编写了一个示例Java客户端代码来连接到APNs服务器以向我的设备发送推送通知。它与APNs服务器的安全连接失败。有人可以帮帮我吗?这是代码:

public class APNSDriver {
    public static void main(String[] args) {
        APNSDriver.sendSamplePushNotification();
    }

    static SSLSocketFactory getSSLSocketFactory() {
        try {
            String keystoreFilename = "D:\\Oracle\\IDCS\\MFA\\APNS\\OMA_prereqs_backup\\iOS_prod.p12";
            char[] storepass = "welcome1".toCharArray();
            FileInputStream fis = new FileInputStream(
                    new File(keystoreFilename));

            final KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(fis, storepass);

            KeyManagerFactory keyManagerFactory = KeyManagerFactory
                    .getInstance("SunX509");
            keyManagerFactory.init(ks, storepass);

            TrustManagerFactory trustManagerFactory = TrustManagerFactory
                    .getInstance("SunX509");
            trustManagerFactory.init((KeyStore) null);

            // create ssl context
            SSLContext sslContext = SSLContext.getInstance("TLS");

            // setup the HTTPS context and parameters
            sslContext.init(keyManagerFactory.getKeyManagers(),
                    trustManagerFactory.getTrustManagers(), null);

            if (keyManagerFactory != null || trustManagerFactory != null) {
                return sslContext.getSocketFactory();
            }
        } catch (Exception e) {
            System.out.println("Unable to create ssl socket factory");
            e.printStackTrace();
        }
        return HttpsURLConnection.getDefaultSSLSocketFactory();
    }

    private static void sendSamplePushNotification() {
        URL url = null;
        try {
            HostnameVerifier hv = new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    return true;
                }
            };

            url = new URL("https://api.development.push.appl.com:443");
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
                    "www-proxy.us.oracle.com", 80));
            HttpsURLConnection conn = (HttpsURLConnection) url
                    .openConnection(proxy);
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setHostnameVerifier(hv);
            conn.setSSLSocketFactory(getSSLSocketFactory());
            OutputStream os = conn.getOutputStream();
            ..........
    }
}

它在conn.getOutputStream()行失败并出现以下错误:     javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:找不到可信证书         at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)         at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)         在sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)         ...................................... sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection。连接(AbstractDelegateHttpsURLConnection.java:185)             at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1282)             在sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1257)             at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)             在com.coding.mfa.apnsdriver.APNSDriver.sendSamplePushNotification(APNSDriver.java:91)             在com.coding.mfa.apnsdriver.APNSDriver.main(APNSDriver.java:28)         引起:sun.security.validator.ValidatorException:找不到可信证书     .............................

1 个答案:

答案 0 :(得分:0)

您需要有效的证书才能连接到该网址。您可以尝试使用可从github(https://github.com/escline/InstallCert)下载的InstallCert.java应用程序,从服务器获取证书,并将其添加到您的信任库。

  1. 下载课程
  2. 设置运行配置添加为程序参数 - > https://api.development.push.appl.com:443 changeit(更改它是信任库的默认传递)
  3. 该应用程序会创建信任库的副本,并从服务器添加证书。
  4. 获取生成的名为" jssecacerts"的文件,将其重命名为" cacerts"并替换java> jre> security> lib文件夹中现有的cacerts文件。
  5. 如果您已经拥有有效证书,并且不需要从服务器获取证书,只需使用KeyStoreExplorer工具打开java> jre> security> lib cacerts文件,然后添加您的证书。然后重新启动本地服务器。请确保进行此更改的java文件夹是本地服务器正在使用的JVM。