How to get WSS4J to load a key password from a callback?

I am using Apache CXF to create a web service. It uses Apache WSS4J to provide WS-Security functionality. I need to make a SOAP request and it must be signed.

This is the contents of the properties file that I am passing to WSS4J:

org.apache.ws.security.crypto.provider = org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type = PKCS12 org.apache.ws.security.crypto.merlin.keystore.provider = BC org.apache.ws.security.crypto.merlin.keystore.password = 12345678 org.apache.ws.security.crypto.merlin.keystore.alias = my-alias org.apache.ws.security.crypto.merlin.keystore.file = my_certificate.p12 

I want to get rid of this line with my password written as plain text. I deleted this line and provided a password callback handler to my WSS4JOutInterceptor, as in the above code:

 public SoapInterceptor newSignerInterceptor() { Map<String, Object> outProps = new HashMap<String, Object>(); outProps.put(WSHandlerConstants.ACTION, "Signature"); outProps.put(WSHandlerConstants.USER, config.getKeyAlias()); outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference"); outProps.put(WSHandlerConstants.USE_REQ_SIG_CERT, WSHandlerConstants.SIGNATURE_USER); outProps.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE, "false"); outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, this.getClass().getName()); outProps.put(WSHandlerConstants.SIG_PROP_FILE, config.getPropertiesFileName()); return new WSS4JOutInterceptor(outProps); } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof WSPasswordCallback) { ((WSPasswordCallback) callbacks[i]).setPassword(password); } } } 

But that did not work. It does not find the password in the properties file and uses the default password, "security".

How to force to use a callback to receive the password?

+6
source share
2 answers

You can implement CallbackHandler :

 public class PasswordCallbackHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for(Callback callBack:callbacks){ if(callBack instanceof WSPasswordCallback){ ((WSPasswordCallback)callBack).setPassword("password"); } } } } 

then add a handler to the properties:

 outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class); 

you can also use PW_CALLBACK_REF to set the handler link.

+5
source

Merlin does not call a Keystore password callback, so the password should always be in the properties file. Fortunately, it can be encrypted.

The solution is well described here: Encrypting passwords in Crypto property files

The copied solution from the link above:

  • Download jasypt-1.9.2-dist.zip
  • Get the encoded password with this command encrypt input=real_keystore_password password=master_password algorithm=PBEWithMD5AndTripleDES
  • Copy OUTPUT (EXample: 0laAaRahTQJzlsDu771tYi)
  • Since you use this algorithm, you need Java Cryptography Extension (JCE) Unlimited Strength. Put in your JDK.
  • Put encoded output in properties

     org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin org.apache.wss4j.crypto.merlin.keystore.type=jks org.apache.wss4j.crypto.merlin.keystore.password=ENC(0laAaRahTQJzlsDu771tYi) org.apache.wss4j.crypto.merlin.keystore.alias=my_alias org.apache.wss4j.crypto.merlin.keystore.file=/etc/cert/my_keystore.jks 
  • In the CallbackHandler, put the master_password with which you used generates encoded:

     public class WsPasswordHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback: callbacks){ WSPasswordCallback pwdCallback= (WSPasswordCallback) callback; final int usage =pwdCallback.getUsage(); if (usage == WSPasswordCallback.SIGNATURE || usage==WSPasswordCallback.DECRYPT) { pwdCallback.setPassword("parKeyPassword"); } if (usage==WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD){ pwdCallback.setPassword("master_password"); } } } 

    }

-1
source

All Articles