Search code examples
certificatesoap-clientws-security

"WSSecurityException: Cannot find key for alias" of a digital certificate in WS-Security SOAP client with Spring Boot


I am trying to make a client to a SOAP with Spring Boot. The requests must have a digital certificate (public key) in the header, but when I try to add it to the secuityInterceptor.

I'm deploying the client on a WildFly server, I thought maybe I would have to add the certificate to the server somehow but I don't know for sure. In principle it is in the resources folder of the project and when generating the war it is still there.

Config:

private static final Resource KEYSTORE_LOCATION = new ClassPathResource("client-keystore.jks");
private static final String KEYSTORE_PASSWORD = "password";
private static final String KEY_ALIAS = "alias";

@Bean
TrustManagersFactoryBean trustManagers() throws Exception {
    TrustManagersFactoryBean factoryBean = new TrustManagersFactoryBean();
    factoryBean.setKeyStore(keyStore().getObject());
    return factoryBean;
}

@Bean
HttpsUrlConnectionMessageSender messageSender() throws Exception {
    HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
    KeyManagersFactoryBean keyManagersFactoryBean = new KeyManagersFactoryBean();
    keyManagersFactoryBean.setKeyStore(keyStore().getObject());
    keyManagersFactoryBean.setPassword(KEYSTORE_PASSWORD);
    keyManagersFactoryBean.afterPropertiesSet();
    sender.setKeyManagers(keyManagersFactoryBean.getObject());
    sender.setTrustManagers(trustManagers().getObject());
    return sender;
}

@Bean
KeyStoreFactoryBean keyStore() throws GeneralSecurityException, IOException {
    KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
    factoryBean.setLocation(KEYSTORE_LOCATION);
    factoryBean.setPassword(KEYSTORE_PASSWORD);
    return factoryBean;
}

@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("contextpath");
    return marshaller;
}

@Bean
Wss4jSecurityInterceptor securityInterceptor() throws Exception {
    Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
    securityInterceptor.setSecurementActions("Signature");
    securityInterceptor.setSecurementUsername(KEY_ALIAS);
    securityInterceptor.setSecurementPassword(KEYSTORE_PASSWORD);
    securityInterceptor.setSecurementSignatureCrypto(cryptoFactoryBean().getObject());
    return securityInterceptor;
}

@Bean
SOAPConnector client() throws Exception {
    SOAPConnector client = new SOAPConnector();
    System.out.println("client(): ");
    client.setInterceptors(new ClientInterceptor[] { securityInterceptor() });
    client.setMessageSender(messageSender());
    client.setMarshaller(marshaller());
    client.setUnmarshaller(marshaller());
    client.afterPropertiesSet();
    return client;
}

Error:

Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during Signature: 
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
    at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:174)
    at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238)
    at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:58)
    at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:609)
    ... 80 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
Original Exception was org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
    at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:615)
    at org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:166)
    ... 83 more
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot find key for alias: [certificado]
    at org.apache.wss4j.common.crypto.Merlin.getPrivateKey(Merlin.java:696)
    at org.apache.wss4j.dom.message.WSSecSignature.computeSignature(WSSecSignature.java:558)

In case it is useful, I am basing myself on this repository to make the client


Solution

  • I think the error is that the functions I'm using are to add certificates with a private key but I try to do it with a public one, in that case I don't know how to add the public one

    this is the sing of the setSecurementUsername method:

    public void setSecurementUsername(String securementUsername)
    Sets the username for securement username token or/and the alias of the private key for securement signature