Java web services: WS-Security without client certificates

Learn how to use WS-Security symmetric encryption for secure exchanges without client certificates

WS-Security symmetric encryption lets you secure message exchanges between client and server without requiring client certificates, simplifying your web service configuration while also providing performance benefits. You can use it directly or in the bootstrap for WS-SecureConversation exchanges. In this article, you'll learn how to configure and use symmetric encryption with the three main open source Java™ web services stacks: Axis2, Metro, and CXF. You'll also see how plain WS-Security symmetric encryption performance compares to WS-SecureConversation performance.

Dennis Sosnoski, Architecture Consultant and Trainer, Sosnoski Software Solutions, Inc.

Author photoDennis Sosnoski is a consultant and trainer specializing in Java-based XML and Web services. His professional software development experience spans more than 30 years, with the last 10 focused on server-side XML and Java technologies. Dennis is the lead developer of the open source JiBX XML Data Binding framework and the associated JiBX/WS Web services framework, as well as a committer on the Apache Axis2 Web services framework. He was also one of the Expert Group members for the JAX-WS 2.0 and JAXB 2.0 specifications. The material for the Java Web Services series is based on Dennis' training classes.



03 August 2010

Also available in Chinese Japanese Spanish

About this series

Web services are a crucial part of Java technology's role in enterprise computing. In this series of articles, XML and web services consultant Dennis Sosnoski covers the major frameworks and technologies that are important to Java developers using web services. Follow the series to stay informed of the latest developments in the field and aware of how you can use them to aid your programming projects.

Many WS-Security configurations require both client and server to use public/private key pairs, with X.509 certificates to vouch for the ownership of the public keys. This is probably the most widely used technique for signing or encrypting messages with WS-Security, and it does have some advantages. In particular, client certificates provide strong client identity verification and strong signature guarantees on requests. But it also has drawbacks, including the performance overhead of asymmetric encryption and the management headaches of obtaining and maintaining certificates for each client.

"WS-SecureConversation performance" showed how WS-SecureConversation — while still working with client certificates — reduces performance overhead for ongoing message exchanges between client and server by using symmetric encryption. In this article, you'll see how you can go a step further and break free of the need for client certificates in both plain WS-Security and WS-SecureConversation exchanges.

Encrypting and signing without client certificates

Using asymmetric encryption with public/private key pairs for signing and encrypting messages is simple (at least conceptually!). As discussed in "Axis2 WS-Security signing and encryption," you use your private key to sign messages and the recipient's public key to encrypt messages. Anyone with access to your public key (which is generally wrapped within layers of authentication in the form of an X.509 certificate) can verify the signature you generated using your private key, whereas only the owner of the corresponding private key can decrypt a message encrypted with a public key.

If the client doesn't have a public/private key pair, you can't use full asymmetric encryption. The alternative is symmetric encryption, but with symmetric encryption you must have a secret key known only to the parties involved in a message exchange. How can you establish such a secret key?

The technique that WS-Security uses is to have the client generate a secret-key value, which is then encrypted using asymmetric encryption with the server's public key and embedded in the request message in a <xenc:EncryptedKey> token. The client can use this secret key (or for better security, a separate key derived from the secret key) to encrypt and/or sign the request message, and the server can do the same with the response message. There's no need for the server to send the secret key back to the client, because the client already has it available.


WS-SecurityPolicy configuration

WS-Policy/WS-SecurityPolicy configuration for symmetric encryption using a client-generated key is simple. Listing 1 shows the version used in this article. This policy specifies encryption of message bodies sent in both directions, using a client-generated secret key.

Listing 1. WS-Policy for encrypting all message bodies
<wsp:Policy wsu:Id="SymmEncr"
    xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
    xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SymmetricBinding>
        <wsp:Policy>
          <sp:ProtectionToken>
            <wsp:Policy>
              <sp:X509Token sp:IncludeToken=".../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>
        </wsp:Policy>
      </sp:SymmetricBinding>
      <sp:Wss11>
        <wsp:Policy>
          <sp:MustSupportRefKeyIdentifier/>
          <sp:MustSupportRefThumbprint/>
          <sp:MustSupportRefEncryptedKey/>
        </wsp:Policy>
      </sp:Wss11>
      <sp:EncryptedParts>
        <sp:Body/>
      </sp:EncryptedParts>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

The <sp:SymmetricBinding> assertion in the Listing 1 policy is what configures the use of symmetric encryption with a secret key. The embedded <sp:X509Token> assertion says that a X.509 certificate will be used to protect the transmission of the secret key (that is, encrypt the secret key for transmission), with the certificate identified using a thumbprint reference (essentially a hash value). Client generation of the secret key is implicit in the use of a <sp:SymmetricBinding> assertion with a <sp:X509Token> protection token. The other policy assertions specify details of the encryption algorithm and required features, and finally the <sp:EncryptedParts> assertion says that the SOAP Body is to be encrypted using the secret key.

As you've seen in earlier articles, run-time parameters for the security handling (such as key stores and passwords) must be defined in an implementation-dependent manner. In this case, the parameters are simple: the client side needs access to a trust store containing the server certificate, and the server side needs access to a key store containing the private key matching the public key in the certificate. See earlier articles in this series for details of how the parameters are passed for each of the stacks.


WS-SecureConversation without client certificates

You can apply the same technique for working without client certificates to the message exchange between the client and the Security Token Service (STS) when using WS-SecureConversation. (See "WS-Trust and WS-SecureConversation" and "WS-SecureConversation performance" for details of WS-SecureConversation.) To use this approach, you basically substitute the Listing 1 policy into the <sp:BootstrapPolicy> for the secure conversation. Listing 2 shows how this works, with the <sp:SymmetricBinding> shown in bold replacing the <sp:AsymmetricBinding> used in "WS-SecureConversation performance":

Listing 2. WS-Policy for WS-SecureConversation without client certificates
 <wsp:Policy wsu:Id="SecureConv"
  xmlns:wsu=".../oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
 <wsp:ExactlyOne>
  <wsp:All>
   <sp:SymmetricBinding>
    <wsp:Policy>
     <sp:ProtectionToken>
      <wsp:Policy>
       <sp:SecureConversationToken
         sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
        <wsp:Policy>
         <sp:BootstrapPolicy>
          <wsp:Policy>
           <sp:SymmetricBinding>
            <wsp:Policy>
             <sp:ProtectionToken>
              <wsp:Policy>
               <sp:X509Token sp:IncludeToken=".../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>
            </wsp:Policy>
           </sp:SymmetricBinding>
           <sp:Wss11>
            <wsp:Policy>
             <sp:MustSupportRefKeyIdentifier/>
             <sp:MustSupportRefThumbprint/>
             <sp:MustSupportRefEncryptedKey/>
            </wsp:Policy>
           </sp:Wss11>
           <sp:EncryptedParts>
            <sp:Body/>
           </sp:EncryptedParts>
          </wsp:Policy>
         </sp:BootstrapPolicy>
        </wsp:Policy>
       </sp:SecureConversationToken>
      </wsp:Policy>
     </sp:ProtectionToken>
     <sp:AlgorithmSuite>
      <wsp:Policy>
       <sp:Basic128Rsa15/>
      </wsp:Policy>
     </sp:AlgorithmSuite>
     <sp:Layout>
      <wsp:Policy>
       <sp:Strict/>
      </wsp:Policy>
     </sp:Layout>
    </wsp:Policy>
   </sp:SymmetricBinding>
   <sp:EncryptedParts>
    <sp:Body/>
   </sp:EncryptedParts>
  </wsp:All>
 </wsp:ExactlyOne>
</wsp:Policy>

Besides using a client-generated key for the message exchange with the STS, the Listing 2 policy also differs from those used in "WS-SecureConversation performance" by eliminating the <wsap:UsingAddressing> assertion.

In theory, this policy should work on any WS-Security and WS-SecureConversation implementation. In practice, some problems occurred when I tried this configuration with the three main open source Java web services stacks. CXF was the only stack that worked with the policy as written. Axis2 didn't work at all, failing with a client-side exception when processing the STS response message. When I changed the bootstrap policy back to asymmetric encryption, Axis2 worked but used WS-Addressing on all messages anyway. Metro also failed; after I added back the <wsap:UsingAddressing>, it worked with a client-generated key for symmetric encryption in the STS message exchange.


Comparing performance

The performance comparisons use the same test code as earlier articles, a seismic data retrieval service. The service uses a database of more than 93,000 earthquakes that occurred worldwide over a period of years. Requests to the service specify a time range and a geographic coordinate range, and the service returns all earthquakes within the specified range. See "The high cost of (WS-)Security" for full details of the test application and a sample request/response message pair.

As in the previous articles, two sets of request sequences are used for the performance tests. The first set uses 1,000 requests, with query parameters adjusted to match a small portion of the entire earthquake database (returning 816 matching earthquakes for the 1,000 requests). The second set uses 100 requests, adjusted to match a larger portion of the database (returning 176,745 matching earthquakes for the 100 requests). These two request sequences emphasize different performance characteristics of web services stacks. The first one shows how quickly stacks process requests with little data, and the second emphasizes the speed of processing data volumes. Each request sequence was run multiple times in different security configurations, with only the best time for each configuration kept in the results. This time, only two security configurations were tested:

  • WS-Security with SymmetricBinding encrypting all request/response message bodies (direct)
  • WS-SecureConversation encrypting all request/response message bodies (securconv)

The securconv configuration is essentially the same as the one used in "WS-SecureConversation performance," the only difference being the use of a SymmetricBinding for the message exchange between the client and the STS with Metro and CXF. Because the tested SymmetricBinding STS policy didn't work with Axis2, the Axis2 configuration used for the timing tests was the same as in the earlier article. The change to using a SymmetricBinding for the STS policy is more for demonstration purposes than for any significant impact on performance, so this difference is not important in the results.

The tests were run on a Mandriva 2009.1 32-bit Linux® notebook with a Turion X2 ZM-85 processor and 3GB of RAM, using a Sun (Oracle) Java 1.6.0_10 32-bit JVM. (Note that this is a different system from the one used for performance tests in earlier articles.) The server code was run on Tomcat 6.0.20, configured to use 1024MB of heap, with the client code using 512MB of heap. The web service stack versions tested were:

  • Axis2 1.5.1 with the 1.5 release of Rampart
  • Metro 2.0
  • CXF 2.1.8

If you want to try the tests on your own hardware and JVM, see Download to get the code.

Performance results

Figure 1 shows the measured times for the small-response test series. As in "WS-SecureConversation performance," Metro is a little faster than CXF (about 10 percent) in the WS-SecureConversation timings. Metro does even better with direct use of symmetric encryption with WS-Security, running about 30 percent faster. (In both of this article's charts, shorter bars are better because they indicate faster times.)

Figure 1. Measured times with small responses
Measured times with small responses

Axis2 results are not included in Figure 1 because of a bug that showed up in the course of the test. The Axis2 test started out running at a reasonable speed but then progressively slowed as the number of iterations increased. The total time to run this test with Axis2 ended up more than 40 times the Metro value. This type of progressive slowing usually indicates an issue such as linear lookups of values being stored by code, in this case within the Axis2 security handling for symmetric encryption (perhaps dealing with the client-generated keys, because a new secret key is generated for each request).

Figure 2 shows the measured times for the large-response test series. Here Metro is again the fastest of the stacks, but CXF comes close — the difference between the two is only about 10 percent. Axis2 is much slower than the other two stacks, as was the case in the WS-Security and WS-SecureConversation tests shown in earlier articles.

Figure 2. Measured times with large responses
Measured times with large responses

These results (except for Axis2) match what you'd expect to see based on the security processing being done. With both security configurations, symmetric encryption is used for the messages exchanged between the client and the service. The big difference between the two is that the WS-Security symmetric encryption configuration uses a new secret key generated by the client for each request/response message pair. This secret key needs to be asymmetrically encrypted using the server's public key and sent as part of the request message, whereas WS-SecureConversation reuses a single secret key across many message pairs. This means the WS-Security configuration adds significant per-request overhead, which shows up mainly in the Figure 1 timings.

The stacks don't support using WS-Security asymmetric encryption for only encrypting a message, instead requiring signing to be done also. This makes it difficult to provide any direct performance comparison, but you can get an idea of the difference by comparing these charts with those from "WS-SecureConversation performance." The earlier article showed that WS-SecureConversation symmetric encryption provides considerably better performance than WS-Security asymmetric encryption, especially for encrypting messages. These results show that WS-Security symmetric encryption with client-generated keys is nearly as fast as WS-SecureConversation, especially for larger messages.


Wrapping up

You've seen in this article how symmetric encryption, using client-generated secret keys, can be used to secure message exchanges without the need for client certificates. This approach offers good performance for message exchanges — nearly as good as WS-SecureConversation — when the messages are relatively large. If only a few messages are exchanged between a client and server, client-generated secret keys can deliver even better performance than WS-SecureConversation secret keys (because WS-SecureConversation requires an extra message exchange, between the client and the STS).

Client-generated secret keys can also be used for signing messages. Though not shown in this article, this use of secret keys is essentially the same as the signing example for WS-SecureConversation discussed in "WS-SecureConversation performance." Signing with secret keys inherently provides weaker guarantees of authenticity than signing with private keys, but it can still be useful for ensuring that messages have not been tampered with in transit.

The last several articles of this series have discussed various forms of WS-Security and WS-SecureConversation security for web services, including performance comparisons for the three main Java web services stacks. I'll cover some specialized WS-Security features in future articles, but for now it's time to wrap up the focus on security performance. The next article of the series will detail the structure of WS-Policy documents and the ways that policies can be attached to services in WSDL, with examples of fine-tuning security configuration for Apache Axis2, Metro, and Apache CXF.


Download

DescriptionNameSize
Sample code for this articlej-jws17.zip5.29MB

Resources

Learn

Discuss

  • Get involved in the My developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, SOA and web services, Open source
ArticleID=504310
ArticleTitle=Java web services: WS-Security without client certificates
publish-date=08032010