org.apache.ws.security.WSSecurityException: General security error (No certificates were found for decryption (KeyId))

mmaceachran picture mmaceachran · Jul 30, 2014 · Viewed 10.5k times · Source

I have inherited some code that is a WSS4J secure webservice. It is based off of this popular tutorial: http://distributedsenses.blogspot.com/2008/09/configuring-cxf-for-web-service.html

Now the server side is working with other clients, but mine is not. :(

I generated a keystore for tomcat, exported the public key, and installed it on the server. But when I tried the call, the server replies with the error No certificates were found for decryption (KeyId)

Now I made some no changes to the code, but I did change the package names (I don't think that matters for SOAP calls) -- I did NOT change the namespaces.

I even exported the cert on the server to make sure that i imported it correctly, and it matches exactly the public key on the client. So I know the server has my cert.

Here is my OutInterceptor

 <bean 
   class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
    id="TimestampSignEncrypt_Request">
    <constructor-arg>
        <map>
            <entry key="action" value="Timestamp Signature Encrypt"/>
            <entry key="user" value="clientwin"/>
            <entry key="encryptionUser" value="tomcat2"/>
            <entry key="signatureKeyIdentifier" value="DirectReference"/>
            <entry key="signaturePropFile" value="clientSign.properties"/>
            <entry key="encryptionPropFile" value="clientEncrypt.properties"/>
            <entry key="passwordCallbackClass" value="ClientKeystorePasswordCallback"/>
            <entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
            <entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
            <entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
            <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
            <entry key="signatureAlgorithm" value="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
        </map>
    </constructor-arg>
</bean>

And my clientSign.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=clientwin
org.apache.ws.security.crypto.merlin.file=C:\\apache-tomcat-7.0.55\\ssl\\.keystore

Any reason why I am getting this error. I KNOW my public key is in the server's truststore. And this works for other clients. Any Idea what I am doing wrong?

Answer

mmaceachran picture mmaceachran · Jul 31, 2014

First, let's understand what's happening and what is going wrong. The client, me, is sending an encrypted request to the server. I need to use the Servers public key to encrypt the message. This is the "encryptionUser" property above. It's value is the alias used when importing servers public key into my keystore. The server will use its private key to decrypt the message.

The reason for any No certificates were found for decryption (KeyId) is that the public key you (the client) are using to encrypt your message, does not match the private key the server has. You need to ask the server to use keytool, export its public key, and then you import it (using keytool) and the alias you use needs to match encryptionUser in the xml.

In my case, the keypair used to encrypt everything was different from the keypair used for HTTPS of the SOAP call itself. So using InstallCert, or simply saving the cert from my web browser while looking at the WSDL as not working.

Hope this helps some noob in the future!