Java Authentication over HTTPS - java

I'm trying to authenticate with a server over HTTPS. I'm having problems with the handshake. I think this is due to the fact that when I go to the URL in my browser, a popup box appears. If I cancel that, I can then go to a form which will allow me to login again. The server security is TAM.
Its actually at the start where I'm having problems. When I try to run this code:
HttpResponse response = httpclient.execute(httpget);
I get an IOException error stating that javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated. The sample code I'm using is from Apache HTTPClient docs. I've tried to also use the built in java authentication methods, but I get other problems with the handshake, saying the certificate isn't trusted.
Anyway, I'm pretty stuck at the moment, which is frustrating because I thought this type of stuff should be basic enough.
So, could someone be so kind as to direct me to some sample code for authentication over HTTPS?
Thanks.
EDIT:
Just to add another error I get when using the built in java http auth, relating to the certificate:
javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.g: PKIX path building failed:
java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is:
java.security.cert.CertPathValidatorException: The certificate issued by CN=XXX Internal Root CA, O=XXX Corporation, C=US is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error

It seems you are missing server SSL certificates in jvm keystore, you need to import certificates using keytool. Here is one link on how to do. Here is another link (even though it is for Gmail, you may find steps useful)

The problem here is Windows. Or more specifically the WinInet API, apparently.
I can create a custom TrustManager that accepts all certs, and it can connect fine. Also, if I try my code without the hack on linux, then it works fine. So whatever way Windows handle the keystore is giving me problems.

Related

Is it possible to disable ssl for https?

Application on java. OkHttp version 2.7.5 is used. A request is made to another service and an error occurs.
SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
I do not have a certificate. It seems there are solutions for the version of okHttp3. But the version can not be changed. How to solve a problem?
Is it possible to disable ssl for https?
Literally, no.
Use of SSL is fundamental to the HTTPS protocol. If you don't want to use SSL at all, configure your server with an HTTP endpoint and use that instead of HTTPS.
Furthermore use of SSL requires a certificate that is (at least) syntactically well-formed. That is also fundamental to the HTTPS protocol.
Now if the problem is that your server certificate has expired, then a possible solution is to use the approach described in:
Make a connection to a HTTPS server from Java and ignore the validity of the security certificate.
And if the problem is that you cannot get a proper certificate for the server (e.g. you can't afford it) then an alternative solution is:
generate a self-signed certificate; see How to generate a self-signed certificate using Java Keytool,
install it on the server side,
configure the client as above to ignore certificate validity.
But note that doing either of those things has security issues.
There is a third solution that is more secure.
generate a self-signed certificate (as above)
install it on the server side,
use Keytool to add the certificate to the client app's keystore as a trusted certificate.

com.ibm.jsse2.util.j: Certificate chaining error while accessing a page through https in notes agent

I have following situation - I want to get page content using https request and java agent. However, I'm getting following error message:
javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.j: Certificate chaining error
I already imported internet certificates to my local notes cacerts file, but nothing changed.
However, when I'm running same code in Eclipse, using keystore with certificates downloaded from page I try to receive and it works fine.
I'm out of ideas, any suggestions will be appreciated!
===EDIT===
Dmytro Pastovenskyi's answer helped me, but additionally to get rid of protocol_version exception I had to use following code, setting version of TLS used:
System.setProperty("https.protocols", "TLSv1");
It seems nessesary to establish connection to some sites using 1.6 IBM JAVA.
I had same issue some times before.
It looks like IBM Domino server more strict when it check certificates. Our administrator who at the beginning said that chain is correct later found an issue with chain (and yes, it worked for .NET/JAVA and other platform, just not with Domino). Try to find some online tools that verify chain.
Before chain is fixed you can simply disabled certificate validation. I've an article how to do it (+ some other articles that may help you). Have a look here: Disabling certificate validation in Java

Java mail TLS authentcation

I am trying to get a grasp on the fundamentals of Java Mail API and TLS. I have the following scenario:
There is an STMP server that uses TLS & SSL. If I log on to this server with some client, I can send authenticated &verified e-mails without any problems.
Then I try to run a web server on a different machine, that sends mail using the previously mentioned SMTP server. I still want to send TLS & SSL emails, however no matter how I configure the startup properties I get the following well known error:
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 found a lot of people having similar issues, however my question is this:
Considering the previuosly described scenario, do I have to get some kind of certificate to the web server (possible somewhere in the JRE), or should it just work fine since the mail server already has that certificate & authentication mechanizm running. Shouldn't it be possible to just use the certificate of the SMTP server? Anyway, if I have to install the certificate to the machine that uses the STMP server how can I get that certificate?
I'm pretty new to JavaMail API and I have seen lots of articles about this but I could not find the answer black & white for my question.
Your client (that is in your case the one running on the webserver) needs to verify the SSL certificate of the mail server. It seems that your java truststore doesn't contain that certificate.
So you either need to put that certificate into the default truststore of your JRE (what I wouldn't recommend) or define a different truststore for your application (that of course needs to contain the mail servers certificate). To do that set this VM parameter: Djavax.net.ssl.trustStore=<path-to-truststore>
Edit: Ah I missed some part of your question.
To get the certificate of the mail server use something like openssl. See for example:
https://serverfault.com/questions/139728/how-to-download-ssl-certificate-from-a-website
The answer is in the JavaMail FAQ.
Quoted text from the linked site:
Q: When connecting to my mail server over SSL I get an exception like "unable to find valid certification path to requested target".
A: Your server is probably using a test certificate or self-signed certificate instead of a certificate signed by a commercial Certificate Authority. You'll need to install the server's certificate into your trust store. The InstallCert program will help.
Alternatively, you can set the "mail.protocol.ssl.trust" property to the host name of your mail server. See the javadocs for the protocol provider packages for details.
Other common causes of this problem are:
There's a firewall or anti-virus program intercepting your request.
There's something wrong in your JDK installation preventing it from finding the certificates for the trusted certificate authorities.
You're running in an application server that has overridden the JDK's list of trusted certificate authorities.

Ignore certificate errors when requesting a URL in Java

I'm trying to print a URL (without having a browser involved at all) but the URL is currently throwing the following:
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'm calling the URL using a JEditorPane's setPage method, which just takes a URL as a parameter. Assuming I can't change anything server side and I still need to get to this resource, how would I go about ignoring the certificate error (or something else that gets me to my goal)?
Accessing this URL via a browser tells me the site is untrusted and asks me if I want to proceed.
Extend JEditorPane to override the getStream() method.
Inside that method, you can open a URLConnection. Test whether it is an HttpsURLConnection. If it is, initialize your own SSLContext with a custom X509TrustManager that doesn't perform any checks. Get the context's SSLSocketFactory and set it as the socket factory for the connection. Then return the InputStream from the connection.
This will defeat any attempts by the runtime to protect the user from a spoof site serving up malware. If that's really what you want…
This is possibly because your certificate in your keystore for accessing target HTTPS URL does not match the certificate from server.
You need to import the certificate in to your JVM's keystore.
Obtain keystore certificatesto access this URL and then importit into the main keystore with
keytool -importkeystore -srckeystore /path/to/custom/keystore -destkeystore $JAVA_HOME/jre/lib/security/cacerts
Assuming you are using Java from $JAVA_HOME
I would use erickson solution.
Another way is to add server's certificate (probably self signed) to your trusted certificates KeyStore (I would do it just in your test enviroment).
Use:
java InstallCert YourHost
to create a jssecacerts file
then copy it to the following folder:
$JAVA_HOME/jre/lib/security
If it is the same server that you will be contacting each time, it might be okay to simply trust this one certificate by adding it to the trust store. I wouldn't add this to the default cacerts file, but you can make your own keystore and specify it through the javax.net.ssl.trustStore system property.
Lastly, if you want to disable PKIX checking completely (which you should only do if you understand that this will compromise security quite a lot) the only way is to implement your own SSL context and trust manager as erickson has suggested.
On a related note: my mutual certifcate authentication with a WCF .net Web Service was causing issues in my test environment. I added these two lines to my code to fix the problem and allow me to work through the issue:
//Uncomment this in case server demands some unsafe operations
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
//this command allowed me to see the detailed debugger log for detecting the
//issue with my certs.
System.setProperty("javax.net.debug","all");
Here is a nice reference for dealing with SSL negotiation and certifcates in a Java/Windows/Unix world: Transport Layer Security (TLS) Renegotiation Issue Readme

Steps to trouble shoot SSL

I am trying to trouble shoot a two way SSL handshake mechanism. I get an error
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This indicates that one of my keystore or my truststore files does not have the appropriate entries. I know the way to trouble shoot this is to go to the server's truststore do the keytool list check the signing authorities and come to the client's key/truststore and verify this.
Can someone list these steps clearly (with the appropriate commands) please? Googling is not leading me anywhere. I just need a list of steps of "How can I confirm that Client X can talk to Server Y with two way SSL using Cert Z"?
The SunCertPathBuilderException exception is thrown whenever there the certificate validator fails to establish a chain between the certificate and a root certificate.
The easiest way to confirm that the certificate validates is to use a graphical tool like
Keyman, or
KeyTool IUI
The above tools are recommended since the exception is usually thrown in the absence of a root certificate.
If you want to examine what certificates are getting exchanged, it is better to switch on the ssl debug flag on the JVM node where the validation is failing.
Another option is to use a network traffic capture utility like Ethereal or Microsoft Netmon to obtain a dump of the traffic containing the certificate exchanges.
PS: Are you using the right keystore in the first place? I remember doing the same mistake many moons ago...

Categories