Question

We are using standard Java/SAAJ features to create SOAP messages and perform web service (WS) calls. So far, communication has been unecrypted across HTTP transport and calling a WS on the endpoint has worked fine using this approach:

SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection con = scf.createConnection();
URL endpoint = new URL(endpointUrl); // configured HTTP URL

// "message" is passed as parameter (a SOAPMessage object)
SOAPMessage response = con.call(message, endpoint);
con.close();

Now our clients wants us to encrypt all traffic using Blowfish. I know I can encrypt arbitrary data using the following simple approach (this example just uses a random secret key):

KeyGenerator kgen = KeyGenerator.getInstance("Blowfish");
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "Blowfish");

Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
String inputString = "This is just an example";
byte[] encrypted = cipher.doFinal(inputString.getBytes());

Cipher decCipher = Cipher.getInstance("Blowfish");
decCipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = decCipher.doFinal(encrypted);

assertEquals(inputString, new String(decrypted));

However, the missing link is: How do I put these two pieces together so that I can encrypt the payload using Blowfish and decrypt it upon receiving the response?

The standard facilities Java provides (SOAPMessage, SOAPConnection and the likes) do not seem to support any encryption at all. I have seen that Spring's WebServiceTemplate supports ClientInterceptor instances which may help with that. However, I would have to rewrite our WS code to use spring-ws, then. And I have not yet found an example in their reference docs which explains how to do this kind of encryption with spring-ws.

Am I missing some easy way to encrypt the communication? If yes, what is it? If not, which good options exist to achieve what the client is asking for?

Update: using HTTPS as secure transport is not an option.

Thanks a lot for your help.

Was it helpful?

Solution

The article is quite long, so it is difficult to summarize here, but you may want to use Web Services Security, and IBM has a great article on that.

http://www.ibm.com/developerworks/java/library/j-jws5/index.html

But, you will have a couple of issues, one is key exchange, for Blowfish, as it needs the same key on the client and server-side, so you risk someone intercepting the key unless you can walk it over on a jump drive for example.

You may want to look at the data and see what parts needs to be encrypted, then you can use RSA to encrypt the symmetric key, pass that as a parameter in your SOAP service, and that key is used to encrypt whichever fields needs to be protected.

By using a public key encryption to do this you can change the Blowfish key on every call, and the key exchange is still secure, as the private key (on the server) is needed to recover the key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top