I have problem with certificate. This is my stack trace:
trustStore is: /usr/user/programs/java/jdk1.7.0_10/jre/lib/security/jssecacerts
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
Subject: EMAILADDRESS=******, CN=865409164, OU=http://www.sistem.net, O=DOO, L=Citluk, ST=Text, C=BA
Issuer: EMAILADDRESS=***********, CN=ecommtest.rbbh.ba, OU=ITRIOSS.CARD, O=BANK, L=CITY, ST=******, C=BA
Algorithm: RSA; Serial number: 0xf6e5b0e213f9b11b
Valid from Tue Jul 30 14:43:23 CEST 2013 until Wed Jul 30 14:43:23 CEST 2014
and at the end I got this:
***
%% Invalidated: [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 2E .......
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
main, IOException in getSession(): javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
main, called close()
main, called closeInternal(true)
I've got certifacte as PKCS12, then I importkeystore by keytool in jssecacerts and copy it in JDK/jre/lib/security
I use apache HttpClient to execute POST request.
Thanks for any help
Zlaja
We have found solution. These are steps:
Run InstallCert from https://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java. It will create jssecacerts.
Backup your cacerts from jre/lib/security
Replace cacerts with jssecacert
Change your code like this:
val clientStore = KeyStore.getInstance("PKCS12")
clientStore.load(new FileInputStream("/home/zlaja/Downloads/imakstore_80009164.p12"), "12348765".toCharArray())
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
kmf.init(clientStore, "12348765".toCharArray())
val kms = kmf.getKeyManagers()
val trustStore = KeyStore.getInstance("JKS")
trustStore.load(new FileInputStream("/usr/user/programs/java/jdk1.7.0_10/jre/lib/security/cacerts"), "changeit".toCharArray())
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
tmf.init(trustStore)
val tms = tmf.getTrustManagers()
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(kms, tms, new SecureRandom())
val schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", new SSLSocketFactory(init), 443))
val client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParameters, schemeRegistry), httpParameters);
I had this problem as well, but I finally have a solution that works for my JAX-WS client with SSL.
The problem in my case was JAX not able to look in another keystore but cacerts, and my certificate has 2 chained which was impossible to import via command line to cacerts.
Related
I am trying to create a bespoke SSL context through code as we are unable to provide keystore.jks using VM arguments -Djavax.net.ssl.trustStore in the code.
I am creating a rest template along the lines:
#Bean
RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
keyStore.getURL(),
keyStorePassword.toCharArray()
).loadKeyMaterial(keyStore.getURL(),
keyStorePassword.toCharArray(),
keySecret.toCharArray(),
(aliases, socket) -> keyAlias
).build();
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory).build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
but I am getting the following error:
http-nio-8080-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I am sure that the certificate is being loaded in as I have -Djavax.net.debug=ssl enabled and I see the following
adding as trusted cert:
...
...
and on the handshake I can see till
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
http-nio-8080-exec-1, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
http-nio-8080-exec-1, WRITE: TLSv1.2 Alert, length = 2
http-nio-8080-exec-1, called closeSocket()
I wrote an Http Client using Apache HttpClient 4.1.13 which call a remote HTTP service using 2way-ssl.
I configured:
keystore.jks : contains the private key and the client certificate
keystore password: the password of keystore.jks
truststore.jks: contains the certificate of CA e intermediate CA of the server
truststore password: the password of truststore.jks
the code:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File(keystore));
try {
keyStore.load(instream, keyStorePassword.toCharArray());
} finally {
instream.close();
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File(trustore));
try {
trustStore.load(instream, trustorePassword.toCharArray());
} finally {
instream.close();
}
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(keyStore, keyStorePassword.toCharArray())
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext,
new String[] {"TLSv1.1","TLSv1.2"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
poolingConnManager = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslsf)
.build());
If I run a java main (JDK Java(TM) SE Runtime Environment (build 1.8.0_231-b11) which does the call, I got a successful connection and I see in the logs
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - Secure session established
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - negotiated protocol: TLSv1.2
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - negotiated cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - peer principal: XXXXX
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - peer alternative names: [YYYYY]
[2022-01-25 17:49:18][][][][][main][DEBUG]o.a.h.c.s.SSLConnectionSocketFactory - issuer principal: XXXXX
If I run the same code with the same keystores and passwords in Docker OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)) I got the following handshake error
http-nio-8080-exec-1, READ: TLSv1.2 Alert, length = 2
http-nio-8080-exec-1, RECV TLSv1.2 ALERT: fatal, handshake_failure
%% Invalidated: [Session-1, SSL_NULL_WITH_NULL_NULL]
%% Invalidated: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
http-nio-8080-exec-1, called closeSocket()
http-nio-8080-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
[2022-01-25 16:47:45][SESSION_NOT_INITIALIZED][10.60.168.202][http-nio-8080-exec-1] [DEBUG]o.a.h.i.c.DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection
[2022-01-25 16:47:45][SESSION_NOT_INITIALIZED][10.60.168.202][http-nio-8080-exec-1] [DEBUG]o.a.h.impl.execchain.MainClientExec - Connection discarded
What should I search ? Any hints?
UPDATE:
The keystore contains the private key and the certificate chain : certificate -> intermediate CA -> Root CA; I don't understand why the client doesn't find the right certificate to send to the server.
In the working test I got this log
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
matching alias: 1
*** Certificate chain
In the failed test I got:
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
It was my mistake and the problem was in totally different point.
The above code was right.
I need to talk to a service which requires CA signed certificates. I have certificates on my own username and the same certificates has been imported at the server side.So that when I send request, I will produce my certificate for authentication with the server and server matches those certificate and send the response back.
When I request the URL in the browser, it automatically selects/asks (In pop-up) with the certificate on my username and when I select that user name the request loads with a proper response.
Now I want to simulate the same thing in Gatling. However in Gatling I am getting a 401 (Unauthorized).
I verified at the server side that when I send the request from browser, I can able to see the certificates are passing but when I send request from Gatling the certificates are not sending along with request for authentication. At the server side it says no certificates found.
I have imported my username CA signed certificates into JDK keystore and sending the request as shown below.
def execute(): ScenarioBuilder = {
val parameters = Map("$filter" -> "${Id}")
val positionsScenario: ScenarioBuilder = scenario("Locations")
.feed(accountFeed)
.exec(requestHandler.getSAPRequest("Locations", parameters))
positionsScenario
}
def getRequest(requestName: String, parameters: Map[String, String]): ChainBuilder = {
val messageBuilder = exec(http(requestName)
.get(s"$uri")
.queryParamMap(parameters)
.check(status.is(200))
)
messageBuilder
}
I have configured my certs using system.property since gatling.conf is not sending the the certificates in the scenario.
System.setProperty("gatling.http.ssl.trustStore.file", "C:/Program Files/Java/jdk1.8.0_111/jre/lib/security/cacerts")
System.setProperty("gatling.http.ssl.trustStore.password", "changeit")
System.setProperty("gatling.http.ssl.trustStore.type", "JKS")
System.setProperty("gatling.http.ssl.keyStore.file", "C:/Program Files/Java/jdk1.8.0_111/jre/lib/security/vikram")
System.setProperty("gatling.http.ssl.keyStore.password", "changeit")
System.setProperty("gatling.http.ssl.keyStore.type", "JKS")
Here are the log from gatling
Session(SAPPositions,4,Map(gatling.http.ssl.keyStore.password -> changeit,
gatling.http.cache.dns -> io.gatling.http.resolver.ShuffleJdkNameResolver#6e027c67,
gatling.http.ssl.trustStore.type -> JKS, gatling.http.ssl.trustStore.password -> changeit,
accountId -> (account_id eq '000194878-182182-AU-AUD'),
gatling.http.ssl.keyStore.file -> C:/Program Files/Java/jdk1.8.0_111/jre/lib/security/vikram,
gatling.http.ssl.keyStore.type -> JKS, gatling.http.referer -> https://d3u.internal.com/sap/op/data/ACCOUNT_LOCATION_API_SRV/locationapi?%24filter=%28account_id%20eq%20%27000194878,
gatling.http.ssl.trustStore.file -> C:/Program Files/Java/jdk1.8.0_111/jre/lib/security/cacerts,
gatling.http.cookies -> CookieJar(Map(CookieKey(sap-usercontext,d3u.internal.com,/) -> StoredCookie(sap-usercontext=sap-client=100; path=/,true,false,1517797866679))))
1517797866640,0,KO,List(),io.gatling.core.protocol.ProtocolComponentsRegistry$$Lambda$458/906347731#1443b002)
=========================
HTTP request:
GET https://d3u.internal.com/sap/op/data/ACCOUNT_LOCATION_API_SRV/locationapi?%24filter=%28account_id%20eq%20%27000194878
headers=
Connection: Keep-Alive
Accept: */*
Accept-Encoding: gzip, deflate
Host: d3u.internal.com
=========================
HTTP response:
status=
401 Unauthorized
headers=
set-cookie: sap-usercontext=sap-client=100; path=/
content-type: text/html; charset=utf-8
sap-system: D3U
www-authenticate: Basic realm="SAP NetWeaver Application Server [D3U/100]"
Transfer-Encoding: chunked
Content-Encoding: gzip
Here are my Server side log:
[Thr 139749210060544] Server-configured Ciphersuites: "TLS_ECDHE_RSA_WITH_AES128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES256_GCM_SHA384:T
[Thr 139749210060544] Mon Feb 5 11:09:34 2018
[Thr 139749210060544] Client-offered Ciphersuites: "TLS_RSA_WITH_AES256_CBC_SHA:TLS_RSA_WITH_AES128_CBC_SHA:TLS_RSA_WITH_RC4_128_S
[Thr 139749210060544] No Client Certificate
[Thr 139749210060544] New session (TLSv1.2, TLS_RSA_WITH_AES128_CBC_SHA)
[Thr 139749210060544] HexDump of new SSL session ID { &buf= 7f19c001306c, buf_len= 32 }
[Thr 139749210060544] 00000: 3e 2d 9e fb b6 f3 bf 63 fb 49 27 75 f3 d8 24 c7 >-.....c .I'u..$.
[Thr 139749210060544] 00010: 90 85 bb ed 5e 39 d6 cc 15 27 25 04 fe 29 44 3f ....^9.. .'%..)D?
[Thr 139749210060544] SapSSLISessionStartFin(sssl_hdl=7f19c0016b50)==SAP_O_K
[Thr 139749210060544] in/out: status = "new SSL session,TLSv1.2,TLS_RSA_WITH_AES128_CBC_SHA, **NO client cert"**
[Thr 139749210060544] <<- SapSSLSessionStartNB(sssl_hdl=7f19c0016b50)==SAP_O_K
[Thr 139749210060544] HttpParseRequestHeader: no content length set
[Thr 139749210060544] HttpParseRequestHeader: no transfer-encoding set
[Thr 139749210060544] HttpParseRequestHeader: Version: 1001
[Thr 139749210060544] HttpParseRequestHeader: Keep-Alive: 0
[Thr 139749210060544] HttpParseRequestHeader: no server port set
[Thr 139749210060544] HTTP request (raw) [5/540445/1]:
[Thr 139749210060544] GET /sap/bc/gui/sap/its/webgui?sap-client=000 HTTP/1.1
[Thr 139749210060544] host: d3u.internal.com
[Thr 139749210060544] connection: Close
[Thr 139749210060544] Connection Info: role=Server, local=vd3u01.internal.com:44300, peer=10.137.249.2, protocol=HTTPS
[Thr 139749210060544] ->> SapSSLGetPeerInfo(sssl_hdl=7f19c0016b50, &cert=7f19e605e990, &cert_len=7f19e605e99c,
[Thr 139749210060544] &subject_dn=7f19e605e988, &issuer_dn=7f19e605e978, &cipher=7f19e605e980)
[Thr 139749210060544] <<- SapSSLGetPeerInfo(sssl_hdl=7f19c0016b50)==SAP_O_K
[Thr 139749210060544] out: cert_len = <no cert>
[Thr 139749210060544] out: cipher = "TLS_RSA_WITH_AES128_CBC_SHA"
In the server side log, it says client certificate not sent. I am suspecting I am sending something wrong in the request or my code itself.
Thanks
I figured it out what's the problem. The certificates which I am producing are not valid certificates to authenticate with the server.
How do I know whether they are valid/invalid?
Just enabled the java debug using the below line
System.setProperty("javax.net.debug", "all") and see the debug line when the gatling initially starts. I see everything empty which is suspicious to me.
keyStore is : C:/Program Files/Java/jdk1.8.0_111/jre/lib/security/vthaduri
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: C:\Program Files\Java\jdk1.8.0_111\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is :
Use javax.net.ssl [Just for debugging purpose]
Also I have used javax.net.ssl instead of gatling.http.ssl for setting trustore and keystore.
Lastly .disableClientSharing
val httpBuilder: HttpProtocolBuilder = http
.disableClientSharing
.baseURL(AppConfig.getRuntimeConfig("endpoints." + environment + ".sap"))
.connectionHeader("Keep-Alive")
.acceptHeader("*/*")
.acceptEncodingHeader("gzip, deflate")
Later I configured everything properly as per galting.
My colleague set up a (Bluemix) secure gateway using mutual auth for our project to use. He tested it with Ruby and CURL and it works fine. but when configuring my Liberty server to use it, I am running in to many issues.
I used the instructions found here.
Basically...
To create a key store for the client, enter the following command. In the following example, key.p.12 is created.
openssl pkcs12 -export -in "[client]_cert.pem" -inkey "[client]_key" -out "sg_key.p12" -name BmxCliCert -noiter –nomaciter –password pass:<password>
Which creates a PKCS12 store. (I use this in server.xml below)
I then added the certs into my keystore.
I then changed my server.xml to have a trust store as referenced in my
<ldapRegistry baseDN="o=ibm.com" host="bluepages.ibm.com" id="bluepages" ignoreCase="true"
ldapType="IBM Tivoli Directory Server" port="636" realm="w3" sslEnabled="true" sslRef="SSLSettings">
<idsFilters groupFilter="(&(cn=%v)(objectclass=groupOfUniqueNames))" groupIdMap="*:cn" groupMemberIdMap="groupOfUniqueNames:uniquemember" userFilter="(&(emailAddress=%v)(objectclass=person))" userIdMap="*:emailAddress"/>
</ldapRegistry>
<ssl id="SSLSettings" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore"/>
<keyStore id="defaultKeyStore" password="xxxxxx"
location="${server.output.dir}/resources/security/key.jks"/>
<keyStore id="defaultTrustStore"
location="${server.output.dir}/resources/security/sg_key.p12"
type="PKCS12" password="xxxxxx" />
Here's issue #1
When I add the trust store, I can no longer authenticate via my LDAP server. It just says invalid user or password. I remove the trust store.. and I can authenticate again. So adding the truststore has some type of affect.
Issue #2. When I remove my LDAP server and just use basic user registry... I can login in.. but when I try and use the secure gateway, I get..
[err] javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
I have imported the certificate from the secure gateway so not sure why I get this?
So two issues.. Using a truststore.. I can no longer auth via LDAP... and second.. cannot connect to the secure gateway even after importing all certs...
Anyone had success using Bluemix with a Secure Gateway (Mutual Auth) from Java?
Requested info (edited)
Enter Import Password:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
friendlyName: portal
localKeyID: 5F A0 D5 5D 68 C5 39 65 7D 24 D7 78 9B CD 7D 01 FB 1B 00 6D
subject=/ST=NC/C=US/L=RTP/O=IBM Corporation/OU=SWG/CN=*.integration.ibmcloud.com
issuer=/ST=NC/C=US/L=RTP/O=IBM Corporation/OU=SWG/CN=*.integration.ibmcloud.com
-----BEGIN CERTIFICATE-----
INFO
4Q==
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
friendlyName: portal
localKeyID: 5F A0 D5 5D 68 C5 39 65 7D 24 D7 78 9B CD 7D 01 FB 1B 00 6D
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
INFO
-----END ENCRYPTED PRIVATE KEY-----
Finally got this to work.
previous code..
. . . .
connection = (HttpsURLConnection) url.openConnection();
Where url was the URL of the Secure Gateway.
Added before this...
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream(KEY_STORE_PATH), "xxxxxx".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, "xxxxxx".toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(TRUST_STORE_PATH), "xxxxxx".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = null;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms, tms, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());`
connection = (HttpsURLConnection) url.openConnection();
Now it works... tx
Some good info in this thread.. LINK
I am trying to send push notification to iPhone using Java-pns but I am getting the following error...
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
This is my code...
String token="95076d2846e8979b46efd1884206a590d99d0f3f6139d947635ac4186cdc5942";
String host = "gateway.sandbox.push.apple.com";
int port = 2195;
String payload = "{\"aps\":{\"alert\":\"Message from Java o_O\"}}";
NotificationTest.verifyKeystore("res/myFile.p12", "password", false);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(getClass().getResourceAsStream("res/myFile.p12"), "password".toCharArray());
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
keyMgrFactory.init(keyStore, "password".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyMgrFactory.getKeyManagers(), null, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
String[] cipherSuites = sslSocket.getSupportedCipherSuites();
sslSocket.setEnabledCipherSuites(cipherSuites);
sslSocket.startHandshake();
char[] t = token.toCharArray();
byte[] b = Hex.decodeHex(t);
OutputStream outputstream = sslSocket.getOutputStream();
outputstream.write(0);
outputstream.write(0);
outputstream.write(32);
outputstream.write(b);
outputstream.write(0);
outputstream.write(payload.length());
outputstream.write(payload.getBytes());
outputstream.flush();
outputstream.close();
System.out.println("Message sent .... ");
For NotificationTest.verifyKeystore I am getting that this valid is File and Keystore.
I am not understanding why I am getting this error.
This is my error log...
** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
<empty>
[read] MD5 and SHA1 hashes: len = 10
0000: 0D 00 00 06 03 01 02 40 00 00 .......#..
** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
** Certificate chain
**
** ClientKeyExchange, RSA PreMasterSecret, TLSv1
[write] MD5 and SHA1 hashes: len = 269
...
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
I am not understanding why Cert Authorities is empty?
I recommend that you use keytool -list to compare the keystore on the client with those known to the server. The handshake error you are getting is because the Server has done it's hello and is expecting a Client Certificate in reply. You are not sending one. To fix this the PKCS12 certificate should be converted to PEM format (using openssl is one way) and then imported into a keystore using the keytool.
I suspect if you fix this by importing a client certificate into the keystore, then you will hit a second error. The second error will be about the empty CA certs - probably because you don't have a CA cert that is known to your server in your keystore. Import your CA and try again.
Looks like you need to install "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files". This solved the issue for me.
To Send Push Notification to iPhone/ iPad I have used JavaPNS.
It is very easy to use and It worked for me.
We can simply follow This to use it.