You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fx-dev@ws.apache.org by "Guy M. Spillman, Jr." <pu...@guyspillman.net> on 2006/03/29 01:57:43 UTC

Problem Using Public Keys Imported Into KeyStore

I am having a problem with using public keys imported into a keystore.  What I
wanted to do was allow any clients using my web service to generate their own
public key, then import that key into the server's keystore file.  However, when
I attempt this, I get the following exception on the Axis server:

org.apache.ws.security.WSSecurityException: Cannot encrypt/decrypt data; 
nested exception is: java.lang.Exception: Cannot find key for alias: clientkey

The only work around I have found is to use the same keystore file on both the
client & server.  But this means that I am also publishing the private key as
well as the public key.  

I have listed the relevant code from a sample project below.  You can download
the full example from http://www.guyspillman.net/wss4j_problem_full.zip.  

Thank you.

Guy Spillman
public@guyspillman.net
============================================================

Generated two keystores using the following commands in windows:
------------------------------------------------------------
REM Create keystores for both the client & server
keytool -genkey
        -keystore server.keystore
        -storepass mystorepassword
        -alias ServerKey
        -dname "cn=ServerKey"
        -keypass mykeypasssord
        -keyalg RSA
keytool -genkey
        -keystore client.keystore
        -storepass mystorepassword
        -alias ClientKey
        -dname "cn=ClientKey"
        -keypass mykeypasssord
        -keyalg RSA

REM Self Certify the keys in both keystores
keytool -selfcert
        -keystore server.keystore
        -storepass mystorepassword
        -alias ServerKey
        -keypass mykeypasssord 
keytool -selfcert
        -keystore client.keystore
        -storepass mystorepassword
        -alias ClientKey
        -keypass mykeypasssord 

REM Export the public key certificates from each key store to file
keytool -export
        -keystore server.keystore
        -storepass mystorepassword
        -alias ServerKey
        -file server.cert
keytool -export
        -keystore client.keystore
        -storepass mystorepassword
        -alias ClientKey
        -file client.cert

REM Import the public key certificate files into the opposite keystore
keytool -import
        -alias ServerKey
        -file server.cert
        -keystore client.keystore
        -storepass mystorepassword
keytool -import
        -alias ClientKey
        -file client.cert
        -keystore server.keystore
        -storepass mystorepassword
------------------------------------------------------------

On the web service client, the following code is in a JAX-RPC handler:
------------------------------------------------------------
//Get Original Soap Message
SOAPMessageContext soapMsgCtx = (SOAPMessageContext) msgCtx;
SOAPMessage soapMsg = soapMsgCtx.getMessage();
Message msg = (Message) soapMsg;
Document unsignedDoc = msg.getSOAPEnvelope().getAsDocument();

//Initialize WSS4J Engine
Crypto crypto =
CryptoFactory.getInstance("net/guyspillman/wss4j/webservice/crypto.client.properties");

// Sign SOAP Message			
WSSignEnvelope signer = new WSSignEnvelope();
signer.setUserInfo("ClientKey", "mykeypasssord");	        
Document signedDoc = signer.build(unsignedDoc, crypto);

// Encrypt Message
WSEncryptBody encryptor = new WSEncryptBody();
encryptor.setUserInfo("ClientKey", "mykeypasssord");
Document cryptSignedDoc = encryptor.build(signedDoc, crypto);

//Send message
DOMSource domSource = new DOMSource(cryptSignedDoc);
soapMsg.getSOAPPart().setContent(domSource);
soapMsgCtx.setMessage(soapMsg);
------------------------------------------------------------

The crypto.client.properites file the handler uses
------------------------------------------------------------
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=mystorepassword
org.apache.ws.security.crypto.merlin.keystore.alias=ClientKey
org.apache.ws.security.crypto.merlin.file=client.keystore
------------------------------------------------------------

On the axis server, added the following entry into server-config.wsdd file:
------------------------------------------------------------
<service name="MyWebService" provider="java:RPC">
 <parameter name="allowedMethods" value="simpleWebService"/>
 <parameter name="className" value="net.guyspillman.wss4j.webservice.WebService"/>
 <requestFlow>
  <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
   <parameter name="action" value="Signature Encrypt"/> 
   <parameter name="passwordCallbackClass"
value="net.guyspillman.wss4j.webservice.PWCallback"/>
   <parameter name="signaturePropFile"
value="net/guyspillman/wss4j/webservice/crypto.server.properties" />
   <parameter name="decryptionPropFile"
value="net/guyspillman/wss4j/webservice/crypto.server.properties" />
  </handler>
 </requestFlow>	
</service>
------------------------------------------------------------

The crypto.server.properties file the above entry uses:
------------------------------------------------------------
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=mystorepassword
org.apache.ws.security.crypto.merlin.keystore.alias=ServerKey
org.apache.ws.security.crypto.merlin.file=server.keystore
#replacing server.keystore with client.keystore will make this example work, but
this would be cheating
------------------------------------------------------------

The code for the PWCallback handle method:
------------------------------------------------------------
for (int i = 0; i < callbacks.length; i++) {
  if (callbacks[i] instanceof WSPasswordCallback) {		    	
    WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
    pc.setPassword("mykeypasssord");
  } else {
    throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
  }
}
------------------------------------------------------------

The full exception:
------------------------------------------------------------
org.apache.ws.security.WSSecurityException: Cannot encrypt/decrypt data; nested
exception is:
        java.lang.Exception: Cannot find key for alias: clientkey
        at
org.apache.ws.security.WSSecurityEngine.handleEncryptedKey(WSSecurityEngine.java:1127)
        at
org.apache.ws.security.WSSecurityEngine.handleEncryptedKey(WSSecurityEngine.java:926)
        at
org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:349)
        at
org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:245)
        at
org.apache.ws.axis.security.WSDoAllReceiver.invoke(WSDoAllReceiver.java:156)
        at
org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
        at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
        at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
        at
org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
        at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
        at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
        at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:453)
        at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281)
        at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
        at
org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
        at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
        at
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
        at
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.Exception: Cannot find key for alias: clientkey
        at
org.apache.ws.security.components.crypto.Merlin.getPrivateKey(Merlin.java:252)
        at
org.apache.ws.security.WSSecurityEngine.handleEncryptedKey(WSSecurityEngine.java:1125)
        ... 30 more
------------------------------------------------------------
 


---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org