The webservice provider given us 3 certificates for testing purpose:
1. Client Test Certificate with private key: abctest.p12
2. Client Test Certificate with public key: abctest.cer
3. Provider Test Certificate with public key: abc.cer
I've added these 3 certificate into "cacerts" truststore using java 'keytool'.
for 3 certificates, i created 3 different alias name: abcp12, abctest & abc in "cacerts" truststore.
And then I test the program, for 1way SSL connection, my program works fine(request to them, they return response).
But when i try to use 2 ways SSL connection, my program does not work. It gives me this error: "received fatal error: bad_certificate"
I've googled but doesn't help me at all.
I've added 3 certificates into my truststore.
I checked the list with command "keytool -list -v" and all the certs are there.
1way ssl is working but 2ways ssl is NOT working with receiving bad certificate error.
Can anyone please help me? Why bad certificate? Something wrong with the way I add the cert into truststore file?
Or is there any way in java coding to IGNORE this 'bad_certificate' exception?
Here is some error I get:
If you care for an example showing how to set up mutual authentication between a web service deployed in GlassFish and a web service client, then do take a look at section 8.3 in the following document: http://www.slideshare.net/krizsan/scdjws-5-study-notes-3085287
thanks for your suggestion. I've noticed most of this related thread you had post a similar reply to all. I would appreciate if you or any members here can at least know my situation here and post a short answer.
I have went through your notes but it still doesn't help me and i'm not working with Glassfish. Mine is just pure java environmental runtime with NO tomcat server.
Appreciate if anyone can help...
Thanks in advance.
Nicky Eng wrote:I've noticed most of this related thread you had post a similar reply to all. I would appreciate if you or any members here can at least know my situation here and post a short answer.
You caught me red-handed, I must admit! I am slightly lazy, so I prefer referring to existing documents when answering questions.
Your problem, as far as I understand, is not a simple one - I recall spending quite some time investigating that area before being able to write my notes.
I have went through your notes but it still doesn't help me and i'm not working with Glassfish.
I feared this much. Well, then I cannot help you, I am sorry.
Also, per this link, http://forums.sun.com/thread.jspa?threadID=784869 , "The server has to trust the client's certificates too. As they are self-signed they have to be added to the server's truststore." Is this applicable to your situation?
Also, you can check this: http://stackoverflow.com/questions/2759911/java-certificate-based-authentication . It is still applicable if the service you are calling is hosted on tomcat. Have all of the steps here been performed: http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html ? Please do every single step. You might have missed one. I see a lot of questions about this on the web, but no one posts a solution
Here is a primer on 2-way ssl authentication: http://publib.boulder.ibm.com/infocenter/tivihelp/v5r1/index.jsp?topic=/com.ibm.itim.infocenter.doc/cpt/cpt_ic_security_ssl_authent2way.html . "Two-way SSL authentication is also referred to as client authentication because the application acting as an SSL client presents its certificate to the SSL server after the SSL server authenticates itself to the SSL client."
Please be sure to post the solution once you figure this out!
WebService provider gives me 3 certificates (testing purpose)
1. client testing certificate with private key: abctest.p12 (password: abctest)
2. client testing certificate with public key: abctest.cer
3. provider-server certificate with public key: abc.cer
I added abc.cer into my cacerts file by using following command:
Result: successfully added.
I add abctest.cer into my cacerts file by using following command:
Result: successfully added.
I add abctest.p12 into my cacerts file by using following command:
I do not understand, adding abctest.p12 into cacerts need an existing alias name ? Even if i pick one of the alias name, it would ask me to overwrite it..shall i overwrite it ? and which alias name shall i overwrite?
I'm confused. abctest.p12 comes with private key ---> is a cert chain ?
anyone help ?
There is also a mutual authentication example here, but please follow instructions at the above link first. Best of luck!
So all certificate given by my provider, I already successfully imported into my java jre's cacerts. I run again my java program, it stuck again with this:
Since i already have imported server cert( abc.cer ), client cert(abctest.cer), and private key client cert(abctest.p12) into cacerts... How come I still can get "bad certificate" ?
Already 1 week passed I still stuck with this issue.
1. Create a server certificate and have it signed by a CA
2. Creating a Client Certificate for Mutual Authentication
We will assume that step 1 was done by your certificate provider. Now, in the section Creating a Client Certificate for Mutual Authentication, the tutorial says "In client authentication, clients are required to submit certificates that are issued by a certificate authority that you choose to accept.". So it looks like the server is not able to verify your certificate. Did you actually follow the instructions from the url in my earlier post? The very first step in the link is to generate the client certificate using this command:
1. Generate the client certificate:
<JAVA_HOME>\bin\keytool -genkey -alias client-alias -keyalg RSA -keypass changeit -storepass changeit -keystore keystore.jks
2. Export the generated client certificate into the file client.cer
<JAVA_HOME>\bin\keytool -export -alias client-alias -storepass changeit -file client.cer -keystore keystore.jks
3. Add the certificate to the trust-store file <J2EE_HOME>/domains/domain1/config/cacerts.jks:
<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias client-alias -file client.cer
-keypass changeit -storepass changeit
1. Did you do steps 2 and 3 above? I did not see any reference to "export" in your posts. The keytool command options you have used are somewhat different that the one in the tutorial link.
2. Is your client a plain java program running on it own? What is the environment & technology? JAX-WS? JAX-RS? GlassFish? JBoss? HttpClient? What all is involved?
Anyway, I found this example: http://javasecurity.wikidot.com/example-item-1 . Hope it helps. And this also: http://stackoverflow.com/questions/2240931/mutual-authentication-with-web-services
Frankly, I don't think this is going to lead anywhere unless you first try to get a tutorial running. The tutorial assumes a certain environment, and you need to have all of that setup. If you are ok with using Netbeans/Glassfish, then this is all much simpler: http://netbeans.org/kb/docs/websvc/wsit.html
Thank you so much for your posting.
I've skipped step 1 and 2 because I thought client certificate has been provided to us by our webservice provider(WSDL) for testing purpose. So there is no need to generate my own(i'm the client in this case) right?
If i generate my own, then what's the point of 'abctest.cer' certificate provided to me by webservice provider?
I can't change/know anything in the server side because i'm just a client who trying to call provider's webservice's function over HTTPS.
So, if the server insist want 2ways SSL, then in my program, there is no way to ignore/skip SSL authentication process......
Answer to your question:
2. My program (client program) use only plain java stand alone with axis.jar. I generated java source code from a WSDL file by using wsdltojava tool. and then i created a engine to call webservice function. Binding to wsdl is fine, but when my engine calling one of the function, it start doing ssl handshake process, and resulted the server (webservice provider) give me alert 'bad certificate'. No tomcat.
the link you posted earlier, i had read them all and i gained better knowledge on ceritificate but not with this 'bad certificate' error though.
So what's next shall i do ?
Before you run the client that access a web service with SSL, you need to set the value of the environment variable, VMARGS. After that, you can run the application as usual. For SSL, set the value of VMARGS to:
For SSL mutual authentication, set the value of VMARGS to:
Here are more links. Hopefully, this is what you need:
If after setting the four system properties, you still have trouble, then I would suggest getting the Netbeans example from the 1st link above to work. Then go from there.
Having said that ... I still agree with Ivan. I think a good way to approach it is:
1. Download Netbeans
2. Download Glassfish
3. Follow the tutorial or, as Ivan suggested, section 8.3 of the excellent and well-researched of Ivan's notes which has absolutely everything you need, get it running (independent of your application), and then just use that client instead of developing your own client from scratch (like in the above link).
This path will be easier for you, and the net result is the same ... a working client application ... with the difference that instead of you writing custom code (like in the above link) to handle the SSL part, you focus on your actual problem and let Axis handle that for you.
what possible could caused this bad_certificate & NULL pointer Exception ?
the process of SSL handshake is this:
1. Server Hello
2. Client Hello
3. Certificate chain
4. found trusted certificate
5. Certificate request
6. Server Hello done.
7. Certificate chain
8. ClientKeyExchange, RSA PreMasterSecret, TLSv1 <-- finished
9. verify_data <-- this process hit error when it reach below process :
what else i can do ?
A couple of more thoughts:
1. We are assuming that the server already has added your client cert to the server's trust store. But this may not be the case. So maybe you can confirm with the web service provider to make sure that your client cert is indeed added to the server.
2. Your client test certificate has a .p12 extension, meaning that its a PKCS12 certificate. So when getting the keystore, you probably need to get the keystore like this: KeyStore.getInstance("PKCS12"). Is this the issue?
If you still have issues, then I would suggest you attach your bare minimum code to your next post and I can try it with some certificates I have. Without the actual code that throws the NullPointerException ... it is difficult to help.
The main problem having the 'bad certificate' simply because of our provider did not import the certificate into the correct server, in this case is the test-server.
The problem is resolved after we had arranged meeting with their technical team.
I'm so happy that now its clear.
Still, many thanks to Srini. You have been very helpful here.
I am also getting same bad_certificate problem. Below is the log sniffet, please help me to come out of this issue.
My server is tomcat (client) and other party is TIBCO web server (server)
06/2012 09:48:07:190 INFO - I/O exception (org.apache.axis2.AxisFault) caught when processing request: Received fatal alert: bad_certificate
26/06/2012 09:48:07:190 DEBUG - Received fatal alert: bad_certificate
org.apache.axis2.AxisFault: Received fatal alert: bad_certificate
at java.lang.Thread.run(Unknown Source)
Caused by: com.ctc.wstx.exc.WstxIOException: Received fatal alert: bad_certificate
... 52 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.FilterOutputStream.flush(Unknown Source)
Please see here for an example: http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html
And here for options: http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug
When running your application, start it with -Djavax.net.debug=all or or one of the other allowed options. You will
be able to figure out the problem yourself.
I wanted to consume secure webservice. , implementing the digital certificate at Webservice client, Please share the views If any.
01. I have generated the client code using Axis2 (WebServiceStub extends org.apache.axis2.client.Stub)
%AXIS2_HOME%\bin\WSDL2Java -uri wsdlURL -p pkgName -d xmlbeans -s
02. I have a certificate MyCertificate.cer generated as per the instructions from the Webservice Provider.
keytool -genkey -alias mykeystore1-keyalg RSA -keystore mykeystore.jks
03. Imported the certificate to the jks file
keytool -import -trustcacerts -alias unicert -file MyCertificate.cer -keystore mykeystore.jks
04. Please help to write the client program using cert file.
If any can write the process of accessing the webservice using cert file would be appreciated , I am cracking my head towards the problem no clue , please help me.