Announcement Announcement Module
Collapse
No announcement yet.
Verifying and decryption not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Verifying and decryption not working

    I have two services communicating, messages in both ways have to be secured. Signed and encrypted but let's go step by step.

    Each one has it's own private key (in the keystore), and it's public key exported into the other one's keystore. So, client signs with his own private key and encrypts with the public key of the server. The server decrypts the message using his own private key and then validates the message using client's public key in his keystore. Then server doeas just what the client did but using his keys, and that's it.

    I managed to get this to work with xwss security interceptor from spring-ws 1.0.3 using some aditional code.

    Tried to port it to 1.5 (just by changing jars) but it didn't work. Okay, things were changed, so what, let's make it work. But I just couldn't (even after a couple of hours in the debug mode and constantly altering the policy file), server was very persistent not wanting to validate client's signature (I left out the encryption in this scenario for simplicity's sake).

    So I said, ok, let's go to wss4j interceptor. Don't know if I like the property-only configuration over xwss policy, but suppose it's easyer for beginners.

    Okay, I wired in the interceptor, crypto objects, keystorehandler (yes, the new one from wss4j package), all the passwords, the keystores remained the same on both ends.

    I just applied signing and verification. The exception I get is this:

    Code:
    2008.04.11 18:53:37 org.apache.xml.security.signature.Reference verify
    WARNING: Verification failed for URI "#id-19350739"
    2008.04.11 18:53:37 org.springframework.ws.soap.security.AbstractWsSecurityInterceptor handleValidationException
    WARNING: Could not validate request: The signature verification failed; nested exception is org.apache.ws.security.WSSecurityException: The signature verification failed
    Got armed with sources from everywhere so i can see code

    The problem is in the Reference class, where the digests (the one that came with the message and the new computed one) get compared and they were not the same.

    Code:
          byte[] elemDig = this.getDigestValue();
          byte[] calcDig = this.calculateDigest();
          boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig);
    ... from org.apache.xml.security.signature.Reference.verify ()

    I did fetch the right key from the keystore since his and clients serial number are the same.

    Then I read in the WS documentation that only SHA1 with RSA algorithm is supported and that's exactly the kind of keys I have (1024 bits, don't know if it's important).

    And finaly, the server configuration, but I don't think that there's anything wrong here.

    Code:
    	<bean class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
    		<property name="mappings">
    			<props>
    				<prop key="partRequest">partEndpointDom4j</prop>
    				<prop key="statsRequest">statsEndpoint</prop>
    			</props>
    		</property>
    		<property name="interceptors">
    			<list>
    				<ref bean="signatureInterceptor"/>
    				<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
    			</list>
    		</property>
    	</bean>
    	<bean id="signatureInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    		<property name="validationActions" value="Signature"></property>
    		<property name="validationSignatureCrypto" ref="serverKeystore"></property>
    	</bean>
    
    	<bean id="serverKeystore" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
    		<property name="keyStorePassword" value="store_password_server"/>
    		<property name="keyStoreLocation" value="classpath:/security/serverKeystore.jks"/>
    	</bean>
    Any help will be greatly appreciated.

  • #2
    Yeah, and when only trying to encrypt i get the encrypted message in the endpoint, no decryption has ever taken place.

    Configuration:

    Code:
    	<bean class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
    		<property name="mappings">
    			<props>
    				<prop key="partRequest">partEndpointDom4j</prop>
    				<prop key="statsRequest">statsEndpoint</prop>
    			</props>
    		</property>
    		<property name="interceptors">
    			<list>
    				<ref bean="encryptionInterceptor"/>
    				<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="encryptionInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    		<property name="validationActions" value="Encrypt"></property>
    		<property name="validationDecryptionCrypto" ref="serverKeystore"></property>
    		<property name="validationCallbackHandler" ref="keyStoreHandler"></property>
    	</bean>
    	<bean id="serverKeystore" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
    		<property name="keyStorePassword" value="store_password_server"/>
    		<property name="keyStoreLocation" value="classpath:/security/serverKeystore.jks"/>
    	</bean>
    
    	<bean id="keyStoreHandler" class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler">
    		<property name="privateKeyPassword" value="key_password_server"/>
    		<property name="keyStore" ref="keyStore"/>
    	</bean>
    
    	<bean id="keyStore"	class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
    		<property name="password" value="store_password_server" />
    		<property name="location" value="classpath:security/serverKeystore.jks" />
    	</bean>

    Comment


    • #3
      Still nothing. I've placed all the right jars in classpath, the keystores and all passwords are correct (the setup i have with spring ws 1.0.3. and xwss works with those exact keystores) but still no go (even tried to place wss4j 1.5.3. in classpath as someone suggested in some other thread). Don't really know what else to do.

      Comment


      • #4
        Try this

        dspoljaric,

        I got digi sigs working by following these steps

        http://forum.springframework.org/showthread.php?t=52204

        I generated the .jks as in the example as well - might be worth checking out, how much trouble is it to re generate the keys?

        Comment


        • #5
          I worked on this same problem for a few days. The only way I could get certificate authentication working (using wss4j or xwss) with spring ws 1.5.0 was to use SAAJ 1.3 on the client and set the client's transformer factory with

          -Djavax.xml.transform.TransformerFactory=org.apache .xalan.xsltc.trax.TransformerFactoryImpl

          This transformer exists in the xalan 2.7.0 jar but it's not the default.

          My guess is that some transformers are modifying the message AFTER the digest is created and therefore, as you pointed out, they do not match when compared on the service side. Again, that's just a guess.

          Can you try using SAAJ 1.3 and this transformer on your client and post the result?

          Comment


          • #6
            dspoljaric,

            Can you post your whole classpath - wss4j only works with spring ws 1.5 and the dependencies have to be correct as stated, has to be saaj 1.3 and jaxp 1.3 as well i think

            Comment


            • #7
              The recreation of certificates has no effect, neither does changing the signature algorithms.

              I surfed through code, and there is one transformer that get's called after securement actions have executed.

              com.sun.xml.messaging.saaj.util.transform.Efficien tStreamingTransformer, and then com.sun.org.apache.xalan.internal.xsltc.trax.Trans formerImpl in the end of the com.sun.xml.messaging.saaj.util.transform.Efficien tStreamingTransformer.transform(Source, Result) method.

              The transformers on the client side change the message. But, the transformers on the server side also change the message, and finaly the digest value before client transformation and after server transformation are the same.

              Changing the transformer factory had no effect. Transformation results were different but digest value stayed the same on both ends.

              That said, here is my classpath (client and server classpath are the same for simplicity's sake)

              activation-1.1.1.jar
              bcprov-jdk13-132.jar
              castor-1.1.2.jar
              commons-logging.jar
              dom4j-1.6.1.jar
              jdom.jar
              jsr173_1.0_api.jar
              jstl.jar
              junit.jar
              mail-1.4.1.jar
              ognl-2.6.9.jar
              opensaml-1.1.jar
              saaj-api-1.3.jar
              saaj-impl-1.3.jar
              serializer.jar
              spring-binding-1.0.5.jar
              spring-webflow-1.0.5.jar
              spring-webmvc.jar
              spring-ws-1.5.0.jar
              spring-xml-1.5.0.jar
              spring.jar
              standard.jar
              wsdl4j-1.6.1.jar
              wss4j-1.5.4.jar
              xalan-2.7.0.jar
              xercesImpl-2.8.1.jar
              xmlsec-1.4.0.jar

              Guess I have to digg even deeper...

              Comment


              • #8
                the only immediate difference i can see is that in my class path i have the JAXP 1.3 jars downloaded from https://jaxp.dev.java.net/servlets/P... 4&folderID=0

                its worth a shot

                Comment


                • #9
                  Switching the jars made validation work, but some other problems came with it.

                  I'm using CastorMarshaller, version 1.1.2., and it needs xalan and xerces jars from spring ws distribution, and as soon as I put them in the lib directory verification goes to fail mode.

                  So from now on it's a marshaller problem and that can be fixed easy

                  Comment


                  • #10
                    Note that I've found a bug which resulted in invalid signatures being created when using WSS4J and SAAJ. It's quite a subtle bug, caused by the DOM Document provided by SAAJ not being in sync with the SAAJ SOAPMessage. Took me 12 hours to find .

                    See http://jira.springframework.org/browse/SWS-345.

                    As a workaround, you can use Axiom, rather than SAAJ, or wait for 1.5.1 (to be released somewhere this weekend).

                    Comment


                    • #11
                      problem decrypting with wss4j

                      Hi dspoljaric,

                      Did you ever get encryption/decryption working with wss4j? I was able to get digital signatures working with wss4j, but not encryption/decryption. I have a similar problem to what you reported - the appropriate parts of the message do show up encrypted on the server, the SOAP looks good, no fault gets thrown, but the encrypted parts never get decrypted and so subsequent processing fails. Stepping through code it looks like Wss4jSecurityInterceptor fails to decrypt the encrypted parts but never throws or logs any error.

                      Thanks,
                      Paul

                      Comment


                      • #12
                        Hi Paul,

                        Could you please test your encryption/decryption application with the latest snapshot? A serious bug has been fixed (the fix is part of spring-ws 1.5.2) that might be the cause of the problem you are having. Your feedback will be appreciated.

                        Comment


                        • #13
                          Hi,

                          just tested the latest snapshot, and it does fix signatures but decryption still isn't working, just like with 1.5 and 1.5.1.

                          Just like Paul said. My endpoint gets encrypted message, no warnings nor exceptions of any kind gets thrown.

                          PS. For the case when I got signatures working, I had multiple versions of xerces and xalan in lib dir. Then I broke it, trying to fix it properly without changing to axiom, but I just could not get it to work again

                          Comment


                          • #14
                            Thanks for the suggestion Tareq and dspoljaric,
                            I have just tested with the 1.5.2 snapshot but still the same behavior.
                            Not sure if it matters, but the bug Tareq mentioned has to do with wss4j with saaj, whereas I'm using wss4j and axiom.

                            Here is the scenario I'm testing: wss4j + axiom, just a vanila encryption test client/server setup.
                            First, I generated the keys this way:
                            server keystore:
                            keytool -v -genkey -alias alias -keypass keypass -keystore serverKeystore.jks -storepass storepass -keyalg RSA -sigalg SHA1withRSA
                            export PEM file for client keystore:
                            keytool -export -alias alias -file alias.pem -sigalg SHA1withRSA -keystore serverKeystore.jks -storepass storepass -rfc
                            import PEM into client store:
                            keytool -v -import -trustcacerts -alias alias -file alias.pem -keystore clientKeystore.jks -keypass storepass -noprompt

                            client config:
                            Code:
                                
                            <bean id="wsEncryptSecurityInterceptor" 
                                    class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
                                    <property name="securementActions" value="Encrypt" />
                                    <property name="securementEncryptionParts"
                                        value="{Content}{http://mycompany.org/schemas}MyRequestRootElement"/>        
                                    
                                    <property name="securementEncryptionUser" value="alias" />
                                    <property name="securementEncryptionCrypto">
                                        <bean
                                            class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
                                            <property name="keyStorePassword" value="storepass" />
                                            <property name="keyStoreLocation" value="classpath:/clientKeystore.jks" />
                                        </bean>
                                    </property>
                                </bean>
                            on the client, I configure WebServiceTemplate to use Axiom like this:
                            Code:
                                  wsTemplate = new WebServiceTemplate();
                                  wsTemplate.setMessageFactory(new AxiomSoapMessageFactory());
                                  ...
                                  wsTemplate.setInterceptors(clientInterceptors); //includes the wsEncryptSecurityInterceptor
                            server config:
                            Code:
                            	<bean id="messageFactory" 
                            		class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
                            	    <property name="payloadCaching" value="true"/>
                            	</bean>
                            ...
                            	<bean
                            		class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
                            		<property name="mappings">
                            			<props>
                            				<prop
                            					key="{http://mycompany.org/schemas}MyRequestRootElement">
                            					MyEndpointRef
                            				</prop>
                            			</props>
                            		</property>
                            		<property name="interceptors">
                                        <list>
                                            <ref local="wsEncryptSecurityInterceptor"/>
                              			<bean
                                				class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
                                            
                                        </list>                    
                            		</property>
                            	</bean>
                            
                                <bean id="wsEncryptSecurityInterceptor" 
                                        class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
                                    <property name="validationActions" value="Encrypt"/>
                                    <property name="securementEncryptionParts"
                                        value="{Content}{http://mycompany.org/schemas}MyRequestRootElement"/>        
                                    
                                    <property name="validationDecryptionCrypto">
                                        <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
                                            <property name="keyStorePassword" value="storepass"/>
                                            <property name="keyStoreLocation" value="classpath:/serverKeystore.jks"/>
                                        </bean>
                                    </property>
                                    <property name="validationCallbackHandler">
                                        <bean class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler">
                                            <property name="privateKeyPassword" value="keypass"/>
                                        </bean>
                                    </property>
                                </bean>
                            In the server log you can see that the Wss4jSecurityInterceptor got called, but when the endpoint tries to handle the request the MyRequestRootElement content is still encrypted:

                            Code:
                            2008-05-07 15:59:23,796 DEBUG [org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor] - Validating message [AxiomSoapMessage {http://mycompany.org/schemas}MyRequestRootElement] with actions [Encrypt]
                            ...
                            2008-05-07 15:59:26,281 DEBUG [org.springframework.ws.soap.server.SoapMessageDispatcher] - Endpoint invocation resulted in exception - responding with Fault
                            org.springframework.oxm.jaxb.JaxbUnmarshallingFailureException: JAXB unmarshalling exception: null; nested exception is javax.xml.bind.UnmarshalException
                             - with linked exception:
                            [org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'xenc:EncryptedData'.]
                            	at org.springframework.oxm.jaxb.JaxbUtils.convertJaxbException(JaxbUtils.java:75)
                            Maybe this will shed some light.

                            Thanks,
                            Paul

                            Comment


                            • #15
                              Sill not working with 1.5.2

                              Just tested the same scenario with 1.5.2, still same error: message gets encrypted on the client properly, but the server fails to decrypt. http://forum.springframework.org/ima...s/confused.gif
                              And no errors as to why decryption never happens.

                              Is anyone else seeing this problem? If someone has encryption/decryption working with wss4j + axiom, please post a hint. Thanks!

                              Comment

                              Working...
                              X