0
votes

my error is this:

org.apache.cxf.interceptor.Fault: Message part {http://www.w3.org/2001/04/xmlenc#}EncryptedData was not recognized. (Does it exist in service WSDL?)

Which is due to setting properties for decoding ecrypted data. My issue is that I am having problems how to do that with apache cxf (Timestamp and Signature works ok).

Here is my part of code:

public WSS4JStaxInInterceptor wss4JStaxInInterceptor() throws Exception {

   WSSSecurityProperties inProperties = new WSSSecurityProperties();
   //inProperties.addAction(WSSConstants.USERNAMETOKEN);
   inProperties.addAction(WSSConstants.TIMESTAMP);
   inProperties.addAction(WSSConstants.SIGNATURE);
   inProperties.addAction(WSSConstants.ENCRYPTION);
   inProperties.setEncryptionUser("xxx");
   inProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("\"C:\\\\Users\\\\miha_\\\\OneDrive\\\\Dokumenti\\\\Job\\\\Lj\\\\Spring\\\\demo\\\\src\\\\main\\\\resources\\\\xxxx.jks"),"xxx".toCharArray());;
   inProperties.setMustUnderstand(false);
   inProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("\"C:\\\\Users\\\\miha_\\\\OneDrive\\\\Dokumenti\\\\Job\\\\Lj\\\\Spring\\\\demo\\\\src\\\\main\\\\resources\\\\xxxx.jks"),"xxx".toCharArray());
   inProperties.setSignatureUser("cbd");
   //inProperties.setSignatureVerificationCryptoProperties(wss4jInProperties());

   //inProperties.setUsernameTokenPasswordType(WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST);
   inProperties.setCallbackHandler(new ClientKeystorePasswordCallback());

   WSS4JStaxInInterceptor wss4JStaxInInterceptor = new WSS4JStaxInInterceptor(inProperties);

   return  wss4JStaxInInterceptor;

}

So I define "loadDecryptionKeystore" in which I get keystore. But where do I define which certificate to take (with setEncryptionUser("xxx"); ?) and where password to access private key in certificate? Should I define also something else, how ?

ps.: this is configuration for server part when receiving request

thank you

1

1 Answers

0
votes

You define which certificate to take by calling setEncryptionUser.

The password for the private key should by supplied by the CallbackHandler that you define by calling setCallbackHandler.
When the password for the private key will be needed, the framework will request it by calling the callback handler with an instance of WSPasswordCallback (see the documentation section about WSPasswordCallback identifiers for details).

A simple example of a callback handler:

/**
 * @see <a href="https://github.com/gmazza/blog-samples/blob/master/cxf_x509_profile/client/src/main/java/client/ClientKeystorePasswordCallback.java">ClientKeystorePasswordCallback</a>
 */
public class ClientKeystorePasswordCallback implements CallbackHandler {

    private Map<String, String> passwords =
            new HashMap<String, String>();

    public ClientKeystorePasswordCallback() {
        passwords.put("myclientkey", "ckpass");
    }

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];

            String pass = passwords.get(pc.getIdentifier());
            if (pass != null) {
                pc.setPassword(pass);
                return;
            }
        }
    }
}