Announcement Announcement Module
Collapse
No announcement yet.
How to encrypt response using client's private key Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to encrypt response using client's private key

    Hello All,

    I've successfully created a secure web service (leverages signature and encryption) along with a client that calls it.

    The client sends a web service request that is encrypted and signed; the server responds with a message that is also signed and encrypted. Both the server and client are able to "talk" to each other successfully.

    My PROBLEM is this: the public key the server uses to encrypt the response is hard-coded in my XWS policy file. What I would *want* (or, think is the correct way) to happen is for the server to encrypt the response message using the public key associated with the certificate that was contained in the request from the client automatically.

    For some context - here is my client XWS policy file:

    Code:
    <xwss:SecurityConfiguration xmlns:xwss="...">
    
    	<!-- All outbound requests will be signed using my client certificate -->
    	<xwss:Sign includeTimestamp="false">
    		<xwss:X509Token certificateAlias="osclientcert" />
    	</xwss:Sign>
    
    	<!-- All outbound requests to be encrypted; "oscert_rsa" is the server's X509 certificate and does exist in my trust store -->
    	<xwss:Encrypt>
    		<xwss:X509Token certificateAlias="oscert_rsa" />
    	</xwss:Encrypt>
    
    	<!-- All response messages from the server are required to be encrypted -->
    	<xwss:RequireEncryption />
    
    	<!-- All response messages from the server are required to have a signature associated with them -->
    	<xwss:RequireSignature requireTimestamp="false" />
    </xwss:SecurityConfiguration>
    And here is my server's XWSS policy file:

    Code:
    <xwss:SecurityConfiguration xmlns:xwss="...">
    
    	<!-- All outbound response messages to be signed using my certificate -->
    	<xwss:Sign includeTimestamp="false">
    		<xwss:X509Token certificateAlias="oscert_rsa" />
    	</xwss:Sign>
    
    	<!-- All outbound response messages to be encrypted -->
    	<xwss:Encrypt>
    
    		<!-- Isn't this bad??!!  I'm hard-coding the fact that the encryption of EVERY outgoing response is going to be performed using the public-key of the trusted client-certificate with alias: osclientcert_1.  There *must* be a way to set this up such that the public-key used to encrypt is the one associated with the certificate that is specified in the request so that it is dynamic.  How do i do this? -->
    		<xwss:X509Token certificateAlias="osclientcert_1" />
    	</xwss:Encrypt>
    
    	<!-- Require that all inbound messages from clients need to be encrypted -->
    	<xwss:RequireEncryption />
    
    	<!-- Require that all inbound messages from clients are required to have a signature associated with them -->
    	<xwss:RequireSignature requireTimestamp="false" />
    </xwss:SecurityConfiguration>
    Please forgive me for I am pretty new to the field of security and building secure software. If I am thinking about this all wrong, a kick in the right direction would be most helpful and appreciated. I read-through the XWS documentation from Sun, but I could not seem to find an answer to my question.
    Last edited by evanspa; Aug 1st, 2008, 08:12 PM.

  • #2
    Just following-up to my own thread...I found a link (which I'm not allowed to post on this board yet) from Sun's XWS documentation regarding "dynamic responses" which is basically what I want to do.

    You have to write your own "SecurityEnvironmentHandler" - has anyone had to do this before? Looking at Spring's KeyStoreCallbackHandler, it already handles:

    + CertificateValidationCallbacks, + DecryptionKeyCallbacks, + EncryptionKeyCallbacks, + SignatureKeyCallbacks, and + SignatureVerificationKeyCallbacks

    So I wouldn't think I would have to write my own; so I'm sort of back to my original question....should the KeyStoreCallbackHandler wired in my server automatically be trying to encrypt the response using the public-key associated with the certificate on the signed-request that is contained in my server's trust store (that's a mouthful!)? Is there something *special* I need to configure in my server's XWS security policy file? Any help would be greatly appreciated - thanks.

    -Paul
    Last edited by evanspa; Aug 1st, 2008, 03:12 PM.

    Comment


    • #3
      Following-up on my own thread again...

      If I edit my server's XWS policy configuration file to look like:

      Server Configuration:
      Code:
      <xwss:SecurityConfiguration>
      
      	<!-- All response messages to be signed -->
      	<xwss:Sign includeTimestamp="false">
      		<xwss:X509Token certificateAlias="oscert_rsa" />
      	</xwss:Sign>
      
      	<!-- All response messages to be encrypted using client's public key -->
      	<xwss:Encrypt />
      
      	<!-- Require that all inbound messages from clients need to be encrypted -->
      	<xwss:RequireEncryption />
      
      	<!-- All inbound messages from clients are required to have a signature associated with them -->
      	<xwss:RequireSignature requireTimestamp="false" />
      </xwss:SecurityConfiguration>
      Client configuration:
      Code:
      <xwss:SecurityConfiguration>
      
      	<!-- All requests need to be signed -->
      	<xwss:Sign includeTimestamp="false">
      		<xwss:X509Token certificateAlias="osclientcert" />
      	</xwss:Sign>
      
      	<!-- All requests to be encrypted using server's public key -->
      	<xwss:Encrypt>
      		<xwss:X509Token certificateAlias="oscert_rsa" />
      	</xwss:Encrypt>
      
      	<!-- All response messages from the server are required to be encrypted -->
      	<xwss:RequireEncryption />
      
      	<!-- All response messages from the server are required to have a signature associated with them -->
      	<xwss:RequireSignature requireTimestamp="false" />
      </xwss:SecurityConfiguration>
      I get the following error on the server when the client submits a request:

      Code:
      2008-08-01 22:34:37,695 [org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor] (AbstractWsSecurityInterceptor.java:241) ERROR - Could not secure response: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''
      org.springframework.ws.soap.security.xwss.XwsSecuritySecurementException: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''
      	at org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor.secureMessage(XwsSecurityInterceptor.java:139)
      	at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleResponse(AbstractWsSecurityInterceptor.java:136)
      	at org.springframework.ws.server.MessageDispatcher.triggerHandleResponse(MessageDispatcher.java:347)
      	at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:224)
      	at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:168)
      	at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
      	at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
      	at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:230)
      	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
      	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
      	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
      	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
      	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
      	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
      	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
      	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
      	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
      	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
      	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
      	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
      	at java.lang.Thread.run(Thread.java:619)
      Caused by: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''
      	at com.sun.xml.wss.impl.misc.XWSSProcessor2_0Impl.secureOutboundMessage(XWSSProcessor2_0Impl.java:96)
      	at org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor.secureMessage(XwsSecurityInterceptor.java:135)
      	... 25 more
      Caused by: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''
      	at com.sun.xml.wss.impl.filter.EncryptionFilter.process(EncryptionFilter.java:164)
      	at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:81)
      	at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:251)
      	at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:172)
      	at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:133)
      	at com.sun.xml.wss.impl.misc.XWSSProcessor2_0Impl.secureOutboundMessage(XWSSProcessor2_0Impl.java:94)
      	... 26 more
      Caused by: com.sun.xml.wss.XWSSecurityException: Unable to locate certificate for the alias ''
      	at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:360)
      	at com.sun.xml.wss.impl.filter.EncryptionFilter.process(EncryptionFilter.java:156)
      	... 31 more
      I'm sort of stuck here...any help would be greatly appreciated.

      -Paul

      Comment


      • #4
        Encrypt response using client-supplied public key in XWSS and WSS4J

        Hello Paul,

        your problem is widely known (named the dynamic response problem - to use the requester-provided certificate to encrypt the response back to the requester). BTW, the subject you've written is wrong - you use the client's public key (from its certificate), not private key to encrypt the response to it!

        Of course the solution exists, but it would be much simpler if you were using WSS4J instead of XWSS, since it wouldn't require writing custom callback handlers.

        In WSS4J one can use a special value to the ENCRYPTION_USER property, which is available under constant USE_REQ_SIG_CERT.

        The constant can be used when configuring WSS4J interceptors programmatically, and its value (useReqSigCert) can be used e.g. in XML descriptors that configure them.

        For example, in Spring-WS one could do:

        Code:
            <property name="securementEncryptionUser" value="useReqSigCert" />
            <property name="securementEncryptionKeyIdentifier" value="DirectReference" />
        Note that the certificate has to be first sent in from the other side so that you can only do this in a response to a message which contained a full certificate (attached using DirectReference or X509KeyIdentifier in WSS$J nomenclature).


        For XWSS, there are no standard callback handlers (called by Sun "security environment handlers") that would extract the X.509 certificate from the original request, so it's up to you to write one.

        Luckily, Sun has published a tutorial on writing one that does exactly what you want (uses the requester-provided certificate to encrypt the response back to the requester):

        http://download.oracle.com/docs/cd/E...ySamples9.html

        The sample application written for that tutorial chapter is named "dynamic-response" and its code can be found here in XWSS SVN:

        http://java.net/nonav/projects/xwss/...namic-response

        Of specific interest to you is the fragment where the security environment callback handler extracts the requester's certificate from the request and returns it for usage in response encryption (line 293):

        http://java.net/nonav/projects/xwss/...ntHandler.java

        You may also want to read the general article on writing callback handlers for XWSS here:

        http://download.oracle.com/docs/cd/E...ityIntro5.html
        Last edited by olo; Sep 15th, 2011, 12:00 PM. Reason: spelling and grammar

        Comment


        • #5
          Thanks a ton olo - I found this extremely helpful.

          I actually made a new thread because it had been so long since I posted this one with no help (I think the fact that I royally screwed-up the subject contributed to this):

          http://forum.springsource.org/showthread.php?t=70024

          So I had been able to find the sample for doing a dynamic response, and I was in the process of hacking Spring's KeystoreCallbackHandler, but I never got a chance to finish it...I am confident though it can be done...

          When I have time, I'll go the WSS4J route since that looks like it will be easier to do based on the info you provided.

          Thanks again!

          -Paul

          Comment


          • #6
            Could someone pls post correct links? None of these work.

            Comment


            • #7
              Originally posted by BradJCox View Post
              Could someone pls post correct links? None of these work.
              Done. They were easily findable using Google, though, just changed locations.

              Comment

              Working...
              X