12

I use JBoss 4.2.3.GA. In previous task I've used base encryption mechanism which JBoss supports (WS-Security). I.e. I used keystore, truststore files for encryption and signing messages. As usually (in standard way) in jboss-wsse-* files were defined aliases of keys that must be used during crypt process. I used ws security configuration from JBoss in Action book.

That's Ok. Encryption works fine.

But in my current task I need to specify aliases for keys manually and dynamically. Task description:

  • I have several profiles. In every profile can be specifiey alias of public key that must be used for encrypting message.

  • I have keystore containing private/public key of server and public keys of clients that will send message to server

  • I need get alias from profile and encrypt message (on client side) using public key specified by this alias.

  • So I need somehow to load data from keystore (it must resides in file system folder, i.e. outside ear file), get appropriate public key from it and then do encryption.
  • After that I need to send message to remote web service (server side) that has private keys for decryption.
  • Here I see several variants for server side logic: web service makes decryption using standard JBoss mechanism or I can do it manually loading keystore data and do decryption manually.

So the questions are about:

  1. Is there a way to specify for JBoss the file system directory to load keystores from?
  2. Can I specify alias for encryption for standard JBoss WSS mechanism to allow jboss to use this information in crypt process?
  3. If I must to do manual encryption/decryption then How can I wrap several Java-objects into WS message and then encrypt it using necessary alias and how to send this message to remote web service manually?

I just don't know how to start, what framework to use and even is it necessary to use external (non JBoss) frameworks for this...

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Zaur_M
  • 737
  • 3
  • 11
  • 18
  • 2
    I found how to specify keystore location using WSS4J framework: http://ws.apache.org/wss4j/config.html org.apache.ws.security.crypto.merlin.keystore.file org.apache.ws.security.crypto.merlin.truststore.file – Zaur_M Jun 16 '11 at 13:08
  • 2
    I realised that it's allowed to load keystores using jbossws-native framework specifying absolute path to keystores. – Zaur_M Jun 22 '11 at 16:21
  • 2
    For example if keystores are resided in /tmp directory then config file looks like this: /tmp/server.keystore ... /tmp/server.truststore ... – Zaur_M Jun 22 '11 at 16:22
  • To allow secured web service work with several clients in the file jboss-wsse-server.xml in section any aliases for encryption must be eliminated. It is called Dynamic encryption: http://community.jboss.org/wiki/JBossWS-WS-SecurityOptions#Dynamic_encryption – Zaur_M Jun 22 '11 at 16:29
  • Last question : how to specify alias for encryption on client side? – Zaur_M Jun 22 '11 at 17:50
  • 2
    If you just enable SSL, would that be sufficient? – Rob Goodwin Nov 10 '11 at 21:59
  • The alias in XML encrypt is just a hint for the other side, to distinquish between keys from a set of allowed keys. If you have one key, "Zaur_M" could be a good alias. – Maarten Bodewes Nov 30 '11 at 01:30
  • WARNING: only using XML encrypt without a real good way of handling integrity and lots of verification is likely to result in an insecure protocol, if only because of padding oracle attacks. – Maarten Bodewes Nov 30 '11 at 01:32

2 Answers2

3

If possible you can use Axis2 and Rampart. I've successfully used them both in a similar situation.

Rampart is an axis2 module for handling security and it exposes an API that allows you to define the key store location and aliases that you want to use, thus allowing you to define it dynamically.

Axis2

Rampart

Sample code:

private static final String CONFIGURATION_CTX = "src/ctx";  
private static final String KEYSTORE_TYPE = "org.apache.ws.security.crypto.merlin.keystore.type";
private static final String KEYSTORE_FILE = "org.apache.ws.security.crypto.merlin.file";
private static final String KEYSTORE_PWD = "org.apache.ws.security.crypto.merlin.keystore.password";
private static final String PROVIDER = "org.apache.ws.security.components.crypto.Merlin";

private static void engageRampartModules(Stub stub)
throws AxisFault, FileNotFoundException, XMLStreamException {
    ServiceClient serviceClient = stub._getServiceClient();

    engageAddressingModule(stub);   
    serviceClient.engageModule("rampart");
    serviceClient.engageModule("rahas");

    RampartConfig rampartConfig = prepareRampartConfig();  

    attachPolicy(stub,rampartConfig);
}

/**
 * Sets all the required security properties.
 * @return rampartConfig - an object containing rampart configurations
 */
private static RampartConfig prepareRampartConfig() {
    String certAlias = "alias";             //The alias of the public key in the jks file
    String keyStoreFile = "ctx/client.ks";
    String keystorePassword = "pwd";
    String userName = "youusename";


    RampartConfig rampartConfig = new RampartConfig();
    //Define properties for signing and encription
    Properties merlinProp = new Properties();  
    merlinProp.put(KEYSTORE_TYPE, "JKS");  
    merlinProp.put(KEYSTORE_FILE,keyStoreFile);  
    merlinProp.put(KEYSTORE_PWD, keystorePassword); 

    CryptoConfig cryptoConfig = new CryptoConfig();  
    cryptoConfig.setProvider(PROVIDER);  
    cryptoConfig.setProp(merlinProp);  

    //Rampart configurations
    rampartConfig.setUser(userName);
    rampartConfig.setUserCertAlias(certAlias);  
    rampartConfig.setEncryptionUser(certAlias);  
    rampartConfig.setPwCbClass("com.callback.tests.PasswordCallbackHandler"); //Password Callbak class

    rampartConfig.setSigCryptoConfig(cryptoConfig);  
    rampartConfig.setEncrCryptoConfig(cryptoConfig);
    return rampartConfig;
}

/**
 * attach the security policy to the stub.
 * @param stub
 * @param rampartConfig
 * @throws XMLStreamException
 * @throws FileNotFoundException
 */
private static void attachPolicy(Stub stub, RampartConfig rampartConfig) throws XMLStreamException, FileNotFoundException {
    Policy policy = new Policy();
    policy.addAssertion(rampartConfig);
    stub._getServiceClient().getAxisService().getPolicySubject().attachPolicy(policy);
}

PasswordCallbackHandler:

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordCallbackHandler implements CallbackHandler {

// @Override
public void handle(Callback[] callbacks) throws IOException,
        UnsupportedCallbackException {
    for (int i = 0; i < callbacks.length; i++) {
        WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i];
        String id = pwcb.getIdentifer();
        switch (pwcb.getUsage()) {
            case WSPasswordCallback.USERNAME_TOKEN: {
                if (id.equals("pwd")) {
                    pwcb.setPassword("pwd");
                }
            }
        }
    }
}

}

Tomer
  • 17,787
  • 15
  • 78
  • 137
0

1&2: Defining keystore for jboss:

<jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.com/ws-security/config 
http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
  <key-store-file>WEB-INF/wsse.keystore</key-store-file>
  <key-store-password>jbossws</key-store-password>
  <trust-store-file>WEB-INF/wsse.truststore</trust-store-file>
 <trust-store-password>jbossws</trust-store-password>
  <config>
     <sign type="x509v3" alias="wsse"/>
     <requires>
        <signature/>
        </requires>
     </config>
</jboss-ws-security>

3: Encryption replacement (and manual too) example described here for axis2: http://www.javaranch.com/journal/2008/10/web-service-security-encryption-axis2.html

McDowell
  • 107,573
  • 31
  • 204
  • 267
Vugluskr
  • 1,426
  • 1
  • 12
  • 12