In memory SSL validation - java

I do not want to do SSL validation using keystore/truststore on client side. The server gives me a cert(in the form of a String) and I want to validate this on the client side in memory. I think this is possible using java TrustManager API but do not know how to implement this. Explanation with examples would be of great help.

Related

Java servlet: only allow own client

Im developing a little serverside api to use with a java client (which i wrote too).
The api is written with jersey (RESTful) und running on a tomcat server. The data it provides is passed to the client as Json-String and all communication is performed via Http.
I now want to ensure that only my own client programm is able to access the api (At the moment, as its http, everyone could receive the json data via an ordinary browser). Therefor, im looking for a way to "identify" my clientside programm to the api with a key or something like that. I first thought about using the user-agent for identification, but this could easily be copied. So i need some kind of key which changes dynamically or something like that.
Whats a good way to do that?
I searched in the net but didnt find a proper answer (maybe wrong keywords?), so im happy for every hint and/or link about that topic.
Edit: The client side programm is an android app. I want to make sure noone is creating a similar app and use my server for his purpose.
If the attacker has a the client in his possession, there's almost no security that can't eventually be compromised.
A good start, that's fairly out of box is bi-directional SSL authentication (Client and Server certificates). This is supported out of the box and requires little code changes.

Spy Java Secure Sockets

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.

2-way SSL for web services on GAE (java)

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.

java WS client-server communication with certificates, what frameworks/apis should i use?

I have simple client-server communication thru WebServices.
Now, I'm using javax.ws.* and Endpoint class (is it a default implementation?) to create server side and Netbeans to create client side.
I have a basic knowledge about certificates etc.
I want clients to use (private?) certificate to sign (encrypt?) messages, so server knows (can identify) which particular client is calling.
So i have to generate private certificates for clients and public certificate for server?
Which APIs/frameworks (buzzwords like JAAS, ws-security, xwss, tls) should i use ?
Maybe just TLS could be enough for that ?
javax.ws.* - is it a reference implementation from Sun ?
I used SAAJ 1.3.4 and it works.
Now i have a question, how can i identify client (clients have unique private keys) can i extract some private key hash from SOAP envelope (to identify client) ?
You can try using Bouncycastle library, it's ligth weight and quite complete.
http://www.bouncycastle.org/java.html
Usually the client asks the server to identify itself and not the other way around. There is an option for a 2 way identification, I'm guessing you need to configure it.
I'd suggest using Axis2 for generating the client/service stub and Rampart for handling the security.
Rampart is an axis2 module that handles most of the security hustle for you.

Webservices client and ssl

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.

Categories