Thursday, January 6, 2011

[WSS4J 1.6] Crypto property change

One of my goals for this blog is to document ongoing changes to the forthcoming WSS4J 1.6 release. This way I will be able to collate all of the entries into a single resource to put on the WSS4J website. I'm mainly going to focus on changes that affect the end-user, as the internal changes are too numerous to mention. Note that these blog posts are not intended to be definitive, as certain things may change before the release goes out.

This entry focuses on some changes to the Crypto property files.  These files are used to load keys and certificates for various WS-Security operations, and are loaded by the CryptoFactory class. CryptoFactory parses a single property in the file:
  • org.apache.ws.security.crypto.provider - WSS4J specific provider used to create Crypto instances (default value is "org.apache.ws.security.components.crypto.Merlin").
WSS4J 1.6 will only ship with this provider, WSS4J 1.5.x ships with a (largely redundant) BouncyCastle provider as well. The rest of the crypto property file is parsed by AbstractCrypto. The old configuration tags that were available in WSS4J 1.5.x are:
  • org.apache.ws.security.crypto.merlin.file - location of keystore
  • org.apache.ws.security.crypto.merlin.keystore.provider - provider of keystore
  • org.apache.ws.security.crypto.merlin.keystore.password - password used to load keystore
  • org.apache.ws.security.crypto.merlin.keystore.type - type of keystore (defaults to java.security.KeyStore.getDefaultType())
  • org.apache.ws.security.crypto.merlin.load.cacerts - whether to load the CA certs in ${java.home}/lib/security/cacerts or not (default is true)
  • org.apache.ws.security.crypto.merlin.cacerts.password - the password to use to load the CA certs (default is "changeit")
  • org.apache.ws.security.crypto.merlin.cert.provider - the provider to use to load certificates
  • org.apache.ws.security.crypto.merlin.keystore.alias - the default keystore alias to use, if none is specified
There are a number of issues with the old configuration values. The Java CA certs were loaded by default (for backwards compatiblity reasons), which slows things down if they're not needed. Secondly, there is no clean separation of the keystore used to obtain private/secret keys, and that used to verify trust on received credentials. Thirdly, some of the config tag names are inconsistent. The new crypto property tags for WSS4J 1.6 are as follows:

Provider tags:
  • org.apache.ws.security.crypto.merlin.keystore.provider - the provider used to load keystores (including the truststore)
  • org.apache.ws.security.crypto.merlin.cert.provider - the provider used to load certificates
These are identical to the 1.5.x provider tags.

KeyStore tags:
  • org.apache.ws.security.crypto.merlin.keystore.file - location of keystore
  • org.apache.ws.security.crypto.merlin.keystore.password - password used to load keystore
  • org.apache.ws.security.crypto.merlin.keystore.type - type of keystore (defaults to java.security.KeyStore.getDefaultType())
  • org.apache.ws.security.crypto.merlin.keystore.alias - the default keystore alias to use, if none is specified
Note that this is identical to the 1.5.x tags, apart from the location of the keystore file. This value falls back to the old value of "org.apache.ws.security.crypto.merlin.file" if it is not specified.

Truststore Tags:
  • org.apache.ws.security.crypto.merlin.load.cacerts - whether to load the CA certs in ${java.home}/lib/security/cacerts or not (default is false)
  • org.apache.ws.security.crypto.merlin.truststore.file - location of truststore
  • org.apache.ws.security.crypto.merlin.truststore.password - truststore password (default value is "changeit")
  • org.apache.ws.security.crypto.merlin.truststore.type - truststore type (defaults to java.security.KeyStore.getDefaultType())
Note that the Java CA certs are not now loaded by default. It is now possible to specify the keystore to be used as the truststore, as well as the password used to load the truststore, and the truststore type. It is not possible to both load a truststore and use the JDK CA Certs.

One final note - when building a validation chain to validate a received credential, WSS4J uses both the truststore and the keystore. This is for backwards compatibility reasons, where the user does not specify a truststore using the new config. The previous sentence applies to WSS4J 1.6.0, but does not apply from WSS4J 1.6.1 onwards. From WSS4J 1.6.1, WSS4J only uses the truststore when building a validation chain if it is specified. If it is not specified, then it falls back to using the keystore. See this issue for more details.

    16 comments:

    1. How about adding ability to supply a preloaded keystore? I recently had to use wss4j in a project that has a configuration framework that provides the keystore instance but not the path to the keystore. I did work around it, but i think it would be nice to be able to supply KeyStore instance.

      ReplyDelete
    2. Thanks for your comment - I fixed this in revision 1059964:

      http://svn.apache.org/viewvc?view=revision&revision=1059964

      You can now set a keystore, truststore etc. on a Crypto instance.

      ReplyDelete
    3. Colm I am trying to build a client that needs to talk to a windows WSE service.
      Will WSS4j allow me to build the derived keys and also encryopt message from a jks with x509 certs.
      Do you have example scripts that use WSS4j to do above.Want to write a java class.

      ReplyDelete
    4. Hi Mahesh,

      Yes, WSS4J supports encryption with derived keys and X.509 certs from a jks.

      If you have a WSDL for the service, you're probably better off using a web services stack like CXF, rather than WSS4J directly, as it will take care of all of the security stuff for you.

      If you really want to work at a low level with the WSS4J API's, then take a look at the tests, e.g.:

      http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/DerivedKeyTest.java?view=markup

      Colm.

      ReplyDelete
    5. This comment has been removed by the author.

      ReplyDelete
    6. First of all thanks a lot for your reply.
      I am using Jdeveloper 10g 10.1.4 on current project and found both Jdeveloper 10.1.4 and 11g werent supporting the policy with derived keys.
      It will be great if I can get this to work with Jdev 10.1.4 with OC4j Webserver.Is tied to Apache webserver.
      Can I use CFX with any other webserver.

      Take a look at this policy and let me know if you think Wss4j will be able to implement the policy

      sp:SymmetricBinding
      xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
      wsp:Policy
      sp:ProtectionToken
      wsp:Policy
      sp:X509Token
      sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never"
      wsp:Policy
      sp:RequireDerivedKeys/
      sp:RequireThumbprintReference
      sp:WssX509V3Token10/
      /wsp:Policy
      /sp:X509Token
      /wsp:Policy
      /sp:ProtectionToken
      sp:AlgorithmSuite
      wsp:Policy
      sp:Basic128Rsa15/
      /wsp:Policy
      /sp:AlgorithmSuite
      sp:Layout
      wsp:Policy
      sp:Strict/
      /wsp:Policy
      /sp:Layout
      sp:IncludeTimestamp/
      sp:EncryptSignature/
      sp:OnlySignEntireHeadersAndBody/
      /wsp:Policy
      /sp:SymmetricBinding

      ReplyDelete
    7. I downloaded CXF and implemented it in oC4j 10.1.3 per instructions on Apache CXF website
      I need to now how to configure wss4j with CXF

      ReplyDelete
    8. Hi Mahesh,

      Yes CXF should be able to support that security policy. You don't really need to know about how to configure WSS4J with CXF, as WSS4J just works under the hood. The best way to find out how to configure security in CXF in general is to take a look at the docs, and also the security samples that ship with CXF:

      http://cxf.apache.org/docs/ws-securitypolicy.html

      Colm.

      ReplyDelete
    9. Colm,
      Do i need Spring framework (Jdeveloper 10.1.3) or can CXF work without spring.I am thinking of creating a simple echo class and then create a client to call it.

      Mahesh

      ReplyDelete
    10. Hi Mahesh,

      Probably best to raise such questions on the CXF users mailing list rather than this blog:

      http://cxf.apache.org/mailing-lists.html

      Colm.

      ReplyDelete
    11. Ok will do that you have been good help.
      I will use the mailing list

      Mahesh

      ReplyDelete
    12. Colm,
      I did some cxf examples and was able to implement ws security via interceptors.
      However I realized I needed to implement ws policy via cxf. I could not make out how wsdl is provided for client.is the wsdl auto detected if the service is secured via ws policy
      My cxfclient files looks like below


      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://cxf.apache.org/jaxws
      http://cxf.apache.org/schemas/jaxws.xsd">
      <jaxws:client id="client" serviceClass="com.sungard.cxf.example.client.IHello" address="http://localhost:9000/HelloWorld">
      <jaxws:properties>
      <entry key="ws-security.signature.properties"
      value="client-sign.properties"/>
      <entry key="ws-security.signature.username" value="clientx509v1"/>
      <entry key="ws-security.encryption.properties"
      value="client-sign.properties"/>
      <entry key="ws-security.encryption.username" value="clientx509v1"/>
      <entry key="ws-security.callback-handler"
      value="com.sungard.cxf.example.client.ClientPasswordCallback"/>
      </jaxws:properties>
      </jaxws:client>
      </beans>

      ReplyDelete
    13. Hi Mahesh,

      Please send all CXF specific questions to the CXF users mailing list.

      Colm.

      ReplyDelete
      Replies
      1. Colm,
        finally got OC4J an CXF to work with the .NET webservice.Deployment was equally a challange

        Thanks for your help

        Mahesh

        Delete
    14. Colm,
      Finally got the client working.but the final road block seems to be an exception
      the signature or decryption was invalid
      I have subscribed to the list and posted the error waiting for it to get approved

      http://cxf.547215.n5.nabble.com/CXF-2-4-1-Client-is-giving-the-signature-or-decryption-was-invalid-td4507027.html

      ReplyDelete
    15. There are a number of issues with the old configuration values. The Java CA certs were loaded by default.


      Home security

      ReplyDelete