I am trying to connect to a webservice over ssl with a client certificate. Is there an elegant way of doing this apart from shoving things like "javax.net.ssl.keyStore" into System.properties.
Any pointers to code examples would be appreciated.
You could just install the cert into the system keystore. (Location varies across platforms, and you will need admin rights).
you might get some samples from the website for this book : http://www.manning.com/kanneganti/
See example code in my article. It shows how to dynamically provide the custom keystore to the HTTPS server as for the WS client. http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/
Not sure if this is fully relevant, but still. This entry describes the way of generating the certificate and installing it on a local system without using the keytool. Probably you could reuse some parts of the (very simple) source code.
Related
I'm trying to call an Italian webservice, but I'm getting an SSLHandshakeException exception. I know this is a security trust problem and I should have a certificate to allow me to communicate using SSL. I would like to know if someone can help me to understand what should be the next steps and how can I generate a valid certificate to communicate with the webservice. Security is not my beach :)
The Italian webservice has a zip folder with a tool for developers and they have there two certificates, but I don't know what I should do with them. YOu can see here: https://sistemats1.sanita.finanze.it/portale/spese-sanitarie/documenti-e-specifiche-tecniche-strumenti-per-lo-sviluppo
Link to the Zip file: (https://sistemats1.sanita.finanze.it/portale/documents/20182/34450/kit730P_ver_20210301.zip/027086e7-385a-6071-ca86-f52077923a85)
You can see my experimental code here: https://github.com/nbentoneves/ws-spring-sts/blob/main/src/main/java/com/github/STSClient.java, feel free to clone and try it.
Note: In the development kit they have a soap project and I was able to call the webservice without needing anything.
STS Test Environment: https://invioSS730pTest.sanita.finanze.it/DocumentoSpesa730pWeb/DocumentoSpesa730pPort
Thanks,
Have a nice code time :)
You need to create a Trust Manager which does not validate certificate chains like the default ones.
Check this:
(How to solve javax.net.ssl.SSLHandshakeException Error?)
I would like to know if there is an easy (or hard) way to spy the secure sockets from a java applet ? (without having the source code)
The goal here is to know exactly what for informations send an (very good obfuscated) applet.
I thought i can simply compile myself a modified java version with a log function but the full source code from java is not available for security reasons...
Set up a proxy server with a security certificate that the applet accepts. Afterwards, you just have to configure your browser to use that proxy and the applet should use the same config.
See Does https prevent man in the middle attacks by proxy server? for how it works technically.
Some things you will need: A proxy than can act as a web server and which is probably reachable with the name of the real server from your browser. You will need to create a valid certificate for this combination which isn't trivial unless the applet is configured to accept certificates from untrusted sources (no CA authority will issue a certificate for, say, "google.com" so that you can feed that to your proxy).
Googling for "man in the middle attack ssl proxy" turns up many links that should be useful.
This article seems to describe an out-of-the-box solution: Understanding Man-In-The-Middle Attacks - Part 4: SSL Hijacking
It doesn't mention applets but Fiddler might fit the bill (from Capturing HTTPS traffic in the clear?)
Just set -Djavax.net.debug=all in the JVM properties. You will get all kinds of output from different layers of the network stack, including the pre-encrypted SSL traffic.
If you're talking about SSL, it wouldn't be secure if that was possible, and it is secure, so it isn't.
We need to implement two-way SSL on Google App Engine, where we send out web service requests using JAX-WS to a server requring 2-way SSL authentication.
How can we set up 2-way SSL for our outgoing web service requests?
We know that javax.net.ssl* is forbidden in the App Engine environment.
Here's an example of our code:
#WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ListenerSoap {
#WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping")
public void ping();
}
#WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL")
public class Listener extends Service
{
public ListenerSoap getListenerSoap() {
return super.getPort(new QName("http://example.com/Listener.Wsdl",
"ListenerSoap"), ListenerSoap.class);
}
}
And an example of above code in use:
ListenerSoap soap = new Listener().getListenerSoap();
soap.ping();
I figure we can store the keystores or any certs needed in the DataStore as binary objects (though how to upload them is still a lil' vague to me).
How can we go about setting the necessary values needed for this web service to authenticate using 2-way SSL?
Thanks for any help
Update:
Through research I've seen this is how it can be done on a traditional server (one with filesystem access):
ListenerSoap soap = new Listener().getListenerSoap();
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12"
However, in this approach, client_cert.p12 is expected to be on the filesystem.
Additionally, SSLSocketFactory, SSLContext, KeyManager, and KeyManagerFactory all aren't allowed on GAE.
Update:
As of GAE SDK version 1.7.7. this should now be possible:
Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections.
GAE 1.7.7 SDK Release Notes
From my restricted knowledge about SSL authorization, it seems you may be missing something of vital importance here; the certificates. Two-way SSL requires the client and server certificates to be in your keystore, which can be either a self-signed certificate( a pkcs12 or pem file, which you can easily generate with a few commands through shell) or a proprietary certificate issued by an authorized company like Thawte or Verisign.
Although I am not sure if that is the problem you are facing, but its good to check it out.
(Also, I am a newbie so please don't downvote my answer, just trying to suggest possible options.)
ListenerSoap soap = new Listener().getListenerSoap();
Hope it improves
Thanks
I know you might not want to hear this, but using SSL is expensive and problematic for two way communication. Depending on how much control you have over the server/client ends, I prefer a simple bi-directional pipe like web sockets and a data packet protocol that can simply implement AES. It really depends on the problem you are trying to solve.
It sounds like there is confusion over simple connection over SSL (https://...) and what is known as "mutual authentication" or "public key infrastructure (PKI)". You can actually do both or one independent of another. With the latter (what I think the original question is referring to), when you make a request to the server, the server will respond to you asking for a certificate which you must present to authenticate yourself.
To answer the specific question above (loading a keystore from binary data), I don't think that is really possible, since it's the Java runtime that picks up on your keystore. The only think you could do is load the bits from your datastore and temporarily write it to disk. Optionally delete it when the application exists. This I have done before and works fairly well. If you do this, I'd recommend using a location likely to be writable (such as System.getProperty("java.io.tmpdir"));), then after writing the file to disk, set the JVM properties (e.g. System.getProperties().put( "javax.net.ssl.keyStore","...");)
You will need App Engine's Socket API for this. This API is in trusted tester mode, so it's not available for everyone.
You can ask for an access gere : https://docs.google.com/spreadsheet/viewform?formkey=dF9QR3pnQ2pNa0dqalViSTZoenVkcHc6MQ#gid=0
2-way SSL (from app hosted in GAE to outside world) is not supported as far as I know. I tried a sample app few months ago and was frustrated to find GAE does n't even support this basic feature.. and the documentations are n't clear either. You won't be able to present client cert when you contact a web-service.. there is no place to store it, the keystore cannot be accessed.
For what i know about two way SSL, you will have no link with Java EE code: two way SSL is a transport layer security: when your client application will try to create a secured HTTP connection (HTTPS) with the serve, the server will ask for a certificate and will approve or not this certificate. If the client certificate is approved, then a secured connection will be established on parties and they are allow to exchange some messages through this tunnel. But this process is done on the transport layer. Your code (on application layer) will never be informed of this process.
In order to established two way SSL, the setup is done on the application server setup for the SSL port.
See related question.
I have a PEM file provided to me and was told that it will be needed in establishing a SSL socket that connects to a c++ server for some API calls. Does anyone know how I can read in the PEM file and connect? I was also given the parapharse password.
It sounds like the PEM file is a client cert for you to use to login to the server. If it is the client cert, and it sounds like it is, you will likely need a ca cert file also to use in validating the servers certificate in order to establish a connection.
The CA certs need to go into a truststore and your client certs need to go into a keystore. In Java, both of these will be JKS (although it has limited support for PKCS12.) There are default keystore/truststore locations for the JRE as well as for each user. You can also specify external locations for these files in your code, as in the examples below. The commons-ssl library seems to be able to support PEM directly, without the need for JKS, but I haven't used it.
The default passphrase for these keystores in Java is "changeit" without the quotes.
This page shows you have to read the PEM into your keystore/truststore. Here is another example.
Once you have your truststore and keystore set up properly, you need to pass the following JSSE system properties to your JVM:
javax.net.ssl.keyStore
javax.net.ssl.keyStoreType
javax.net.ssl.keyStorePassword
javax.net.ssl.trustStore
javax.net.ssl.trustStoreType
javax.net.ssl.trustStorePassword
You may specify them as -D parameters to the JRE or, as in the examples below, programatically.
Once you finish that, heres a commons-ssl example of creating a socket. Also, heres the Java api for SSLSocket. Heres also an example that doesn't use any apache commons.
You need a library that handles SSL. As John Ellinwood noted, some frameworks (such as Java 2 SE) offers these built-in, for others you'd need to use 3rd party libraries.
C developers often use openssl directly, but it can't be said to be easy and when using C++ there are several "gotchas" that are easy to fall into.
I suggest you use a C++ network library with support for SSL, such as QT's network library, or Poco NetSSL. See here for some tutorial documentation and here for the API documentation - you probably want to take a look at initializeClient which takes a PEM file directly.
I have a Java client that calls a web service at the moment using the Http protocol.
When i try to use the Https protocol i keep getting this error
java.io.IOException: DerInputStream.getLength(): lengthTag=127, too big.
Any ideas what could be up?
Thanks
Damien
Due to american export regulations in encryption technologies, you can't use strong encryption out of the box. Your error looks like you (or your framework) is trying to use strong encryption, and other parts of the framework is not allowing it.
A discussion of a case that looks similar to yours can be found here.
A good crypto provider is BouncyCastle. Takes some reading, but it's not that hard to make it work.
Good luck,
Are you sure you are connecting your HTTPS client to the server port that talks over HTTPS (TLS/SSL) rather than HTTP?
YOu have to pass the keystore type from the client. This error should go then.