How to include a SSL certificate in the rest call - java

Hi i am new to security domain. So please let me know if i am missing something very obvious.
I am trying to create an application that runs on https and requires a SSL certificate.
i followed the this blog to create a ssl certificate and add it to the java security cacerts.
Now i want to create a https post request to this application. The request fails every time. What i found till now is
The certificate is not verified, thats why it is not authorizing the rest call to proceed.
When i open the application in browser, it asks me to confirm the certificate, once i accept it, all rest calls start working.
Can any one tell me what can i do to avoid this(confirming the certificate.)
1. Can i bypass the ssl certificate check ?
2. Can i add certificate to every rest call.
3. Anything else that i should try.
4. I saw looking at this grails plugin, how do i create a .jks file ?
Ay help will be appriciated.

You can't bypass the certificate check on the clients' side. A very important point of having a certificate at all is for it to be signed by a trusted authority. If you have signed it yourself, you can still have an encrypted connection, but the clients can't know you're verified by a trusted third party.
You can configure the application or web server to use the keystore that your certificate is in in order to attach it to every https request. Look up tomcat ssl configuration.
I would advise that you read up a bit more on https and certificates, it's important to understand some details.
It's preferable that you delegate the ssl management to the application server instead of doing that in your rest calls yourself. See 2. Also, a .jks is just a keystore file. You already have one from the tutorial you've followed.

Related

JAXWS. ClientTransportException: The server sent HTTP status 403

I've generated classes from wsdl with wsimport, wsdl location: https://somehost/wsdl. There was no problem with generation.
But when I tried to send soap request, I've received exception:
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 403: Client certificate required
I find out, surfing the internet, that I have to add certificate in my keystore. I've done it, but this doesn't help.
And I have no idea what to do or even what to google.
Can anybody help me?(
It sounds like a mutual authentication problem.
The server is requiring that your client use a known digital certificate to sign your messages and send that information within the request. It is like a user/password mechanism, but you and the server agree to use a known key-pair for identification.
This situation usually means that the web service server administrator will generate a key-pair and send the private part of the certificate to you.
But you can send the public certificate for him as well if you created it yourself. The server must have access to the public certificate, and it maybe you will have to publish it to a Certification Authority. In some cases it has to be a commercial certificate (you will have to buy it).
You will then use the private key to digitally sign your messages.
I've found some links that may help:
Authentication Mechanisms
Java client for the X.509 secured web-service
Java HTTPS client certificate authentication
If you already did those steps, then something is wrong with your implementation or the certificate/keys provided are invalid.
I recommend you to use a mock server to make sure you are implementing the client authentication properly before you try to connect to the real service. Making it to work locally will set the knowledge you need to call the real functions. You can also ask the web service administrator to send you debug information.

Can a signed certificate be used without importing explicitly?

I've read a lot of articles regarding the import of a cert, but I am still unclear on a couple things.
When connecting to an SSL site from a Java application [in this case, a JBOSS web app], does the client cert need to be explicitly installed on the application server prior?
I can install a client cert manually, but there is an expiration date. So I'll need to manage the expiration dates of all client installed certs on our application server, and take an outage to update each one.
It feels like there should be a better way.
Shouldn't the application automatically accept a valid signed cert? [In this case, it is signed by VeriSign]
We are getting an exception currently when trying to access an https url from the application without explicitly installing the cert.
The API proxy library is swallowing the internal exception, so I dont know the details.
If the cert should be accepted automatically, then there may be a different issue here...
Can a signed certificate be used without importing explicitly?
Yes, it does not need to be installed prior to use. In fact, if you know in advance of what to expect, then you can include that information into the application. That has an added benefit of improving the application's security posture.
To avoid importing the certificate, use a custom X509TrustManager and override checkServerTrusted. In checkServerTrusted, ensure the server's public key is expected (i.e., pin the server's certificate or public key); or verify the server's certificate is valid (i.e., is within validity and forms a chain to your trusted root).
When connecting to an SSL site from a Java application [in this case, a JBOSS web app], does the client cert need to be explicitly installed on the application server prior?
In the case of client certificates, the server advertises the issuer whom it relies upon to issue client certificates. So the server will need to know the trust point for issuing client certifcates for authenticating clients.
In this case, it is signed by VeriSign
This could be really bad. In this case, you will trust all of your clients signed under the Verisign PKI, and all of Verisign's other clients signed under the Verisign PKI.
In this case, it would probably be better to avoid public CAs and run your own PKI (i.e., be your own CA). In this case, pick up a copy of Network Security with OpenSSL. The book will show you how to accomplish the customary tasks using both the openssl command and programmatically.

CAC authentication in a Java WebApp

I saw that there were a few other Java and CAC posts on stackoverflow. I am a beginner with all of this stuff and I am still trying to a framework of what to do and where to go in my mind.
I am doing work for a big org that is using CACs with Windows 7 boxes to authenticate users who want to get into their PCs. They stick the CAC in their keyboard and type in a PIN.
My boss would like to alter our Java Webap such that it will not make the users authenticate if they have their CAC in their computer. If not, they will go through the traditional LDAP login.
We are using WebLogic 11g and Java 6.
From Googling around it seems like there are two approaches:
Implement an applet to read the user's CAC and send an SSL certificate to the webapp.
Implement "mutually SSL authentication" in the web server, which will cause the browser to send the SSL certificate on the CAC to the webapp
Do I have a correct appraisal of my options?
Which solution is easier?
Which will be less hassle, more robust in the long run?
I know next to nothing about SSL, which seems to be common in both solutions. I've found a few SSL tutorials that go on at length about abstract concepts. Can anyone recommend a good tutorial for what I want to do?
Thanks much in advance for any information or tips
Steve
Implement an applet to read the user's CAC and send an SSL certificate to the webapp.
Implement "mutually SSL authentication" in the web server, which will cause the browser to send the SSL certificate on the CAC to the webapp
You will want to do #2. You don't really want to have to mess with smart card hardware / software. Let the OS do all that work.
I've done this on IIS, but generically, to implement this, you will need to configure your web server to require client certificates and to trust the DoD CAs. You may need to configure your web server to advertise to clients which CAs it trusts. If the Win7 clients have a client cert that is signed by a CA you trust, the client will attempt to use it. If it's a smartcard certificate, Windows will automatically prompt the user for the pin; you don't have to worry about that. If the user types the correct pin, the cert will be sent to your web server which should then be able to validate the certificate with the CA. If it's a valid certificate, your software can then parse the fields in the certificate and use the values to help authenticate the user (ie whether, despite having a valid certificate, the user is actually allowed to login based on their name / email address/ etc). It's up to you how to handle it from there.
You will have a much easier time figuring this out and finding information if you forget that the users are using a smartcard or a CAC, and just start with the idea that you're going to use client certificates for authentication. Start by creating a self-signed CA test cert. Then create a server cert for your webserver and a client-certificate signed by your test CA. Add the test CA cert as trusted root cert on the client and the server. Then attempt to write a small test app that uses the client cert to authenticate to your webserver. Once you have that working, you can add the DoD CA and try to pull the info out of a CaC certificate.
good luck!

CXF SSL secured Web Service client with multiple certificates

I have a Java CXF client that connects to a SSL secured Web Service with mutual authentication.
I have my keystore and my truststore properly configured on the client-side and it works fine.
I am concerned here by the fact that my keystore contains only one client certificate and on the CXF configuration it is not possible to say "ok for this SSL communication you'll use this certificate".
As I only have one certificate it's not difficult to choose the good one for CXF durign SSL handshake.
But this client will be deployed in a environment where it will be used with multiple possible client having their own certificate and each of them will be signed by the same certification authority. When the server will ask for a client certificate that is signed by a specific authority, there will be no way to distinguish one certificate from another.
How can I tell CXF (or Java) to use the proper certificate in this context?
Do I need to build as many SSL context as client certificates? (ie. having N keystore each of them containing only one certificate).
Or is there a way (in CXF conf or in Java) to say "use this certificate in this context"?
Thanks in advance for your help.
All the certificates must refer to the same client, otherwise the CAs are derelect in their duty. So they should all have for example the same subjectX500Principal. So why do you need a specific certificate? All of them identify the same client, so from an authentication point of view they are all equivalent.
It's starting to sound as though you want to use a particular certificate for authorization purposes, not just to establish identity via authentication. If so it is the wrong approach, a misuse of PKI. Authorization is an application-controlled step once you have an authenticated identity: get the identity of of the peer certificate and look up your authorization database to see if that identity is allowed to access this part of the application. Don't try to use a cacerts file as an authorization database, that's not what it's for.
I don't know if this is an option for you but I've done dynamic alias selection using WSIT before (i.e. one keystore, many private key entries). See this article for more detail. (Let me know if that article isn't enough - I can post more detail if you need)

Enabling https for Java Webstart

I have a swing application deployed in HTTP Server. Users use the browser to point an URL and install the client using java webstart. Now I need to enable https access to my application deployed on HTTP server. I am using JDK 1.5 as default jdk supported in the jnlp file. For time being I use a self signed certificate to the sign the jars (by default created using Sun's jarsigner, keytool, etc, utils).
Solution/steps would be much appreciated.
Thanks in advance
Ramesh
As far as I understand your question you don't need to change anything to your code of the client. If you only want to give access to the JNLP via HTTPS you would only need to reconfigure the application server distributing the JNLP or if you have a webserver in front of the application server (as we do here: user - https -> apache -> AJP -> tomcat) you need to reconfigure the webserver to allow the access to the JNLP via HTTPS.
You need to enable HTTPS on the web server. To get the certificate you need to provide credentials and the host name of the server to a certificate authority (CA) like VeriSign or Thawte. They can provide you with a server certificate signed by their root certificate or some intermediate certificate. This certificate must then be imported into the web server to enable HTTPS over SSL. The web clients, like a browser or webstart will then verify the certificate chain when accessing the server.
If you use a self signed jar, all your users will be presented with a warning message about potentially unsafe code. To avoid this you should get a code signing certificate from a CA, which would be somewhat similar to the web server certificate. This CA-provided certificate can be imported into the keystore and used in the same way you use the self signed certificate. The code signing certificate will be signed by the CA so that the certificate chain can be verified by webstart.
What is the feature of https that you are hoping to leverage?
The signing/server authentication is done by code signing, though you are undermining this using a self-signed certificate.
Does your application code contain secrets that must be hidden from eavesdroppers?
As you say you "need to enable" there must be an underlying reason.
I believe that before you "need https" you need a proper code signing certificate. You might want to rephrase your question so that your underlying problem can be solved instead of the very specific question.

Categories