简体   繁体   中英

SSLHandshake exception while connecting to APNs

I writing a sample Java client code to connect to APNs server to send push notifications to my device.Its failing in the secure connection to APNs server.Can someone please help me out? Here's the code :

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();
            ..........
    }
}

Its failing at the line conn.getOutputStream() with following errors : javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) ...................................... sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1282) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1257) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250) at com.coding.mfa.apnsdriver.APNSDriver.sendSamplePushNotification(APNSDriver.java:91) at com.coding.mfa.apnsdriver.APNSDriver.main(APNSDriver.java:28) Caused by: sun.security.validator.Validato rException: No trusted certificate found .............................

you need a valid certificate to connect to that url. You can try using InstallCert.java app, that can be downloaded from github ( https://github.com/escline/InstallCert ) , for getting the certificate from the server,and add it to your truststore.

  1. Download the class
  2. Set Run configurations adding as program params-> https://api.development.push.appl.com:443 changeit (Change it is the pass by default of the truststore)
  3. The app creates a copy of your truststore and adds to it the certificate from the server.
  4. get the generated file called "jssecacerts", rename it to "cacerts" and replace the cacerts file existing on your java>jre>security>lib folder.

If you already have a valid certificate, and dont need to get it from the server, just use KeyStoreExplorer tool, for openning java>jre>security>lib cacerts file, and add your certificate. Then restart your localserver. Please make sure that the java folder where you make this changes is the JVM that your local server is using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM