Export (0) Print
Expand All
Expand Minimize

WS-Security Interoperability Using WSE 2.0 and Sun JWSDP 1.4

 

Simon Guest
Microsoft Corporation

September 2004

Applies to:
   Microsoft .NET Framework 1.1
   Microsoft Visual Studio .NET 2003
   Microsoft Web Services Enhancements (WSE) 2.0 SP1
   Sun Java Web services Developer Pack (JWSDP) 1.4

Summary: This article shows WS-Security Interoperability between Microsoft WSE 2.0 and Sun JWSDP 1.4. The walkthroughs in this article will take you through all you need to know to configure the two environments for securely signing and encrypting SOAP requests and responses using X509 certificates. (21 printed pages)

Click here to download the source code for this article.

Contents

Required Software and Skills to Run the Code Samples
What Is WS-Security?
Hang on! What's Wrong with SSL?
Installing and Configuring the Sample Code
Configuring WS-Security for Both WSE 2.0 and Sun JWSDP 1.4
Setting up the X509 Certificate Stores
Using X509 to Sign Messages
Using X509 to Encrypt Messages
Conclusion

Required Software and Skills to Run the Code Samples

What Is WS-Security?

WS-Security is a specification to enable security for Web services; specifically through message integrity, message confidentiality, and single message authentication. The WS-Security specification was co-authored by Microsoft, IBM, and Verisign.

On April 6 2004, OASIS (http://www.oasis-open.org) released OASIS Web services Security 1.0 based on this specification. This standard includes recommendations for SOAP message security with profiles for using username and X509 tokens to enable security.

Many vendors are providing implementations of WS-Security. Microsoft offer WS-Security support in WSE (Web Services Enhancements) 2.0, a download from MSDN that compliments the Web services support in the .NET Framework. Sun offer support for WS-Security in JWSDP (Java Web services Developer Pack) 1.4, which can be downloaded from their site.

This article covers techniques to send secure messages between the .NET Framework and J2SE using Microsoft WSE 2.0 and Sun JWSDP 1.4, both of which support the OASIS WSS 1.0 standard.

For more information on WS-Security, I recommend Don Smith's WSE 2.0 WS-Security article, which can be found here.

Hang on! What's Wrong with SSL?

SSL is a proven way of securing resources available on the Internet today. If you've ever purchased anything online it's likely that you've used SSL to securely purchase your goods. This begs the question – why not use SSL with Web services?

As most of today's Web services implementations are based on HTTP, it is entirely possible to use SSL to encrypt the communication and to validate the client and server using certificates. Before the release of the WS-Security specification, many customers already used SSL to do this.

In the Web services world however, SSL does have some limitations:

  • SSL is only good for point to point communication

    SSL works by encrypting the transport channel between two points. For a Web Service call this is from the client to the service. The problem with using SSL arises if the message is routed between multiple points.

    SSL has to be used to secure the communication between all the points on the network, (which makes it difficult to verify that the message was signed by the client). Also, the message is only secure when it's being communicated. If I were able to gain access to one of the points (for example, compromising one of the servers) it's possible that I could read the contents of the message in the clear.

  • SSL is bound to HTTP

    The Web services stack (as defined by the WS-I Basic Profile 1.0) doesn't explicitly bind Web Service usage to HTTP. It's feasible that as Web services implementations mature we'll see support for other transports, including TCP, SMTP, FTP, IBM MQSeries, and MSMQ. We are already seeing examples of these today with WSE 2.0. The format of the message remains the same, but the underlying transport changes.

    For all these other transports, SSL is not an option. For some of these transports (for example, TCP), a secure option for that channel may not even exist. In these instances, security at the message level using WS-Security guarantees that the message itself is secure rather than relying on the security model of the underlying transport. Using WS-Security in this way offers a more flexible way of security the message regardless of the transport used.

  • WS-Security can persist signed or encrypted messages

    WS-Security specifies that the security elements are part of the message. Because of this it is possible to persist signed messages to disk, which can be useful is a non-repudiation situation. (Non-repudiation is where you are trying to prove that a signature is attributed to an individual).

    Imagine that you are running a secure Web Service and at some point you wanted to prove that a call had been made from an individual. In an environment that uses SSL this could be difficult. It is possible to log the request, but the security parts of the message (the client signature) are automatically removed by the transport.

    With WS-Security, the signed elements are applied to the message – meaning that they can be persisted to disk, with the message contents. In this situation you could use examine these elements to prove that the message was indeed signed by an individual at a point in time.

Installing and Configuring the Sample Code

To help show interoperability using WS-Security between Microsoft WSE 2.0 and Sun JWSDP 1.4, this article is accompanied with sample code. This sample code can be downloaded here.

When installing the sample code, you will be prompted for an installation directory. The default is c:\wssinterop\jwsdp14. Although you are free to specify your own directory, the walkthroughs in this article assume you are using this default.

Installing and Configuring WSE 2.0

If you have not already, you should install Microsoft WSE 2.0, the download for which can be found here. The installation is straightforward; however it is recommended that you choose Visual Studio Developer as the installation type as shown in Figure 1. This will ensure that the correct options are installed for integration with Visual Studio .NET 2003.

ms954606.interopsun-01(en-us,MSDN.10).gif

Figure 1. The WSE 2.0 SP1 Install Wizard

Installing and Configuring JWSDP 1.4

Sun JWSDP 1.4 supports three containers to host Web services: Sun Java System Application Server Platform Edition 8, Sun Java System Web Server 6.1, and Tomcat 5.0 for JWSDP.

This article is based on using Tomcat 5.0 for JWSDP 1.4. This specific version of Tomcat can be downloaded here. For working with the sample code, it is recommended that Tomcat is installed to the default directory, c:\tomcat-jwsdp-1.4.

After Tomcat 5.0 is installed, install Sun JWSDP 1.4. During the installation wizard, ensure that the container is set by specifying the location of the Tomcat installation directory. You can do this by clicking on the browse button shown in Figure 2 and selecting the Tomcat 5.0 directory.

ms954606.interopsun-02(en-us,MSDN.10).gif

Figure 2. Selecting the Tomcat Container in the JWSDP 1.4 Installation Wizard

When prompted for the Tomcat administrators information, use a username of admin and password of changeit (these can be changed later).

The Sample Web Service

If you've ever purchased anything from an online store, it's likely that you will have entered your credit card details into a Web page form. As discussed earlier in the document, SSL will have likely been used to secure the transport.

In this sample you are going to see how to create a similar operation using Web services, but securing the communication using WS-Security. The will look similar to the one shown in Figure 3.

ms954606.interopsun-03(en-us,MSDN.10).gif

Figure 3. Overview of the Sample Web Service

As shown above, the operation is fairly simple with the customer sending credit card information to the Web Service. On receipt of the information, the Web service returns a tracking number to the customer.

To do this a SOAP request will be constructed that contains the following information:

OrderID—A field identifying the order

CreditCardNum—A field holding the number for the credit card

CreditCardExpM—A field holding the month of expiry for the credit card

CreditCardExpY—A field holding the year of expiry for the credit card

An example of this could be:

   OrderID—298532

   CreditCardNum—4622-1234-5678-9012

   CreditCardExpM—04

   CreditCardExpY—05

Once the payment information is received, the Web Service will return a tracking number. This can be thought of as a receipt. In this sample this is a random number generated on the server.

Representing This in XSD

For the sample you'll be working with, the format of the credit card payment information has been generated using XSD (XML Schema Definition). Doing this before writing classes is good practice for situations that require interoperability as it is representative of the data that will be sent on the wire.

The XSD file, which can be found in the c:\wssinterop\wsdp14\schemas folder, looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ComplexMessages" 
targetNamespace="http://schemas.wsig.samples.microsoft.com/ComplexMessages.xsd" 
elementFormDefault="qualified" 
xmlns="http://schemas.wsig.samples.microsoft.com/ComplexMessages.xsd" 
xmlns:mstns="http://schemas.wsig.samples.microsoft.com/ComplexMessages.xsd" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Order">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:long" />
<xs:element minOccurs="0" maxOccurs="1" name="CreditCardNum" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="CreditCardExpM" type="xs:int" />
<xs:element minOccurs="0" maxOccurs="1" name="CreditCardExpY" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>

As can be seen above, the order ID, Credit Card number and expiration are defined in the XSD file. You can use an XSD editor such as Microsoft Visual Studio .NET 2003 to view and manipulate this file as you wish.

While the XSD file is useful for designing the data types, there is still a need to get these converted into classes on each platform. Fortunately, there are tools available that will do this.

A utility called xsd.exe is part of the .NET Framework SDK, and can be found in the SDK directory of the Visual Studio .NET installation. xsd.exe is used to generate a class from the XSD document. For Sun JWSDP 1.4, xjc.bat is a tool that comes with the JAXB implementation. This tool will convert the XSD to a Java type. After this is done the type can then be used within a Web Service.

To save you time, the tools have already been used to generate the required classes from this XSD file. These classes are included in the sample code. If you wish to regenerate the data types based on this schema, use the generate.bat batch file in the schemas folder. This will generate the required classes for the Java Web Service, and will update the source code accordingly.

Building the JWSDP 1.4 Web Service

To test the sample you must first build the JWSDP 1.4 Web Service. To do this, and with all the pre-requisites installed, run the build.bat batch file in the c:\wssinterop\wsdp14\wsdp\service\OrderService directory. You should run this batch file from the command prompt in case of errors. This will compile the Web services source code and create the Web services deployment.

Once compilation is complete, the deployment will be copied to the Tomcat installation. OrderService.war and OrderService-portable.war, the two WAR files that make up the deployment can be found in the webapps directory of the Tomcat installation. With a default installation, this will be: c:\tomcat-jwsdp-1.4\webapps.

Starting the Apache Tomcat Server

After deployment is successful, it's time to start the Tomcat server. From a command prompt, navigate to the bin directory of the Tomcat installation (c:\tomcat-jwsdp-1.4\bin). From here, run the following command:

catalina run

This will start the Tomcat server.

Note   It is possible to start the Tomcat server using other commands (for example, startup.bat in the same directory or by using the Program Files menu option). Using the above command however ensures that all error messages and information is displayed in the current console window.

When the Tomcat server is starting, look for indications that OrderService.war was correctly deployed:

Jul 29, 2004 4:24:57 PM org.apache.catalina.startup.HostConfig deployWARs
INFO: Deploying web application archive OrderService.war
Jul 29, 2004 4:24:57 PM org.apache.catalina.core.StandardHostDeployer install
INFO: Installing web application at context path /OrderService from URL jar:file
:C:\tomcat-jwsdp-1.4\webapps\OrderService.war!/

When startup has completed, you can run the client.

Building the Client

If you have Microsoft Visual Studio .NET 2003 installed, you can use the solution file included to build and run the client. This file is WSS.sln and is found in the c:\wssinterop\wsdp14\dotnet directory.

Note: If you do not have Microsoft Visual Studio .NET 2003, you can use the build.bat file in the Client subdirectory. Run the Client.exe file to run the client.

Build and run the client. You should observe the following:

Creating order...
Sending payment information to Sun JWSDP 1.4 Web Service...
Submit complete.  The tracking number for this order is: 1855259209

As shown, the order is created and sent to the Sun JWSDP Web Service. This completed and a tracking number was returned to the client.

Congratulations! The Web Service is now working correctly! Let's look at what is being sent across the wire.

Enabling Tracing

Before we look at the steps involved to use WS-Security, it is a great idea to look at how tracing has been setup. This will allow you to inspect the SOAP requests and responses as they travel between the client and the server. This is a useful way to confirm whether a message is sent encrypted or in plain text.

For the sample code accompanying this article, tracing has automatically been enabled for the WSE 2.0 client and the Sun JWSDP 1.4 service.

For WSE 2.0, all messages are written to the InputTrace.webinfo and OutputTrace.webinfo files in the c:\wssinterop\jwsdp14\dotnet\bin\debug directory (these will be the dotnet directory if you use the build batch file).

Tracing with WSE is enabled by using the <trace> setting in the app.config file, or by using the WSE 2.0 configuration editor, which you will investigate later in this article.

For Sun JWSDP 1.4 all messages are written to the Tomcat console. This is enabled through the dumpMessages="true" setting found in the wsse.xml file of the service. When you enable WS-Security later in the article, this will be activated.

After running the client, look at the OutputTrace.webinfo file. You can see the credit card information is sent in plain text:

<soap:Body>
<submitOrder xmlns="http://wss.samples.microsoft.com">
<OrderImpl_1 xmlns="">
<id>348922</id>
<creditCardNum>4426-1234-5678-9012</creditCardNum>
<creditCardExpM>10</creditCardExpM>
<creditCardExpY>5</creditCardExpY>
</OrderImpl_1>
</submitOrder>
</soap:Body>

The InputTrace.webinfo file shows that the tracking number from the service is also returned in a similar way.

<env:Body>
<ns0:submitOrderResponse>
<result>179688114</result>
</ns0:submitOrderResponse>
</env:Body>

Now that we've seen the type of information that is being sent in the clear (known as plain text), let's look at how we can use WS-Security to sign and encrypt this information.

Configuring WS-Security for Both WSE 2.0 and Sun JWSDP 1.4

Microsoft WSE 2.0 and Sun JWSDP 1.4 differ slightly in the way that you configure WS-Security for each platform.

WSE 2.0 can be configured programmatically in code or by using a configuration file based on an early implementation of WS-Policy. The WS-Policy specification shows how elements of a Web Service can be configured through external XML files, and is neutral of the vendor implementation. For the samples shown in this article we will show enabling WS-Security options using WS-Policy, but remember that you could also achieve this same functionality through code.

Sun JWSDP 1.4 can also be configured programmatically or through external XML files, although today these are not based on WS-Policy. We will show samples of these configuration files throughout the document.

Setting Up the X509 Certificate Stores

Before you implement WS-Security to sign and encrypt these messages, it is necessary to first configure the X509 certificates and stores.

As the sample will be showing signing and encrypting messages in both directions (from WSE 2.0 to JWSDP 1.4 and vice versa), you need to setup some certificates and keys. For this sample, a combination of the keys and certificates provided in both the Microsoft WSE 2.0 and Sun JWSDP 1.4 quick start samples will be used. All these certificates are for test use only, and you are free to use or generate your own for these samples.

This is how the sample works:

ms954606.interopsun-04(en-us,MSDN.10).gif

Figure 4. Signing and Encryption between the Client and Service

The WSE 2.0 client holds a private and public key (pK1 and PK1 in the diagram) and the public key of the JWSDP 1.4 service (PK2). The JWSDP 1.4 Web Service holds a private and public key (pK2 and PK2) and the public key of the WSE 2.0 client (PK1).

When the WSE 2.0 client signs a request to the JWSDP 1.4 Web Service, it uses the private key (pK1) to generate a signed hash of the message. This can be represented as S(sub pK1)(M). The public key is also be sent with the message to allow that the Sun JWSDP service to verify the signature (creating S(sub pK1)(M),PK1).

When the WSE 2.0 client encrypts a request to the JWSDP 1.4 Web Service it will use the public key of the Sun Web Service (PK2) to generate the cipher text (E(sub pK2)(M)). The Sun JWSDP service uses the corresponding private key (pK2) to decrypt the message.

These operations work in reverse when the Sun WSDP 1.4 service signs and encrypts the responses to the WSE 2.0 client.

The certificates and keys used to perform this differ between the client and the service. For the client, the Windows CurrentUser certificate store is used. For the Sun Web Service, a JKS (Java Key Store) is used.

As you will be using the JKS from the Sun JWSDP 1.4 samples, copy the server-keystore.jks file and the server-truststore.jks files from the JWSDP sample directory (c:\jwsdp-1.4\xws-security\etc) into the c:\wssinterop\jwsdp14\certs directory. The server-keystore.jks file contains the key pair used to sign messages from the server. The server-truststore.jks file contains the certificates needed to validate the certificate chain for a request.

Configuring Certificates on the Microsoft Client

The WSE 2.0 client will be using the Windows store to access X509 certificates and corresponding private keys. To import the required certificates into this store:

First, double click on the Client Private.pfx file in the sample directory of the WSE 2.0 installation (c:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates). Follow the certificate import wizard to install the certificate and private key. The password for the private key is wse2qs. When asked for the location of the store, ensure that Personal is used.

This sets up the public and private key required to sign the SOAP requests. Next we have to import the public part of the certificate used by the JWSDP 1.4 service, and also the public part of the issuing certificate authority. To export the public part of the certificate, open a command prompt and navigate to the c:\wssinterop\jwsdp14\certs directory.

From here, run the following two commands:

keytool –export –file server.cer –alias s1as –keystore server-keystore.jks

(when prompted enter the default password for the JKS, which is changeit)

keytool -export -file ca.cer -alias certificate-authority -keystore server-truststore.jks

Again, when prompted enter the default password.

These two commands will create two certificate files, server.cer and ca.cer. From this directory in Windows explorer, double click on each of these files to view them, and click on the Install Certificate button. Ensure that the certificate in server.cer is imported into the Personal store and the certificate in ca.cer is stored in the Trusted Root Certification Authorities store.

Setup of the Windows store is now complete.

Configuring the JKS (Java Key Store)

The certificate and corresponding private key for the JKS are already present in the files that you copied from the Sun JWSDP sample directory. There is therefore no need to recreate these.

You do however need to import the public part of the certificate (PK1) that will be used to sign encrypted responses sent to the WSE 2.0 client. To do this, open MMC (the Microsoft Management Console) by running mmc.exe from the Start/Run menu option in Windows. With the MMC open, select File->Add/Remove snap-in and select the Certificates snap in option. Click on the Add button, select My User Account and close the dialog to return to the MMC console.

Navigate to the personal folders. The list of certificates installed should look similar to those shown in Figure 5.

ms954606.interopsun-05(en-us,MSDN.10).gif

Figure 5. MMC view of the Certificate Store

To export the public part of the client certificate, right click on the WSE2QuickStartClient and select All Tasks->Export. Do not export the private key (if prompted) and select Base 64 CER as the export type. For the export file name, use c:\wssinterop\jwsdp14\certs\wse2client.cer.

Besides exporting the WSE2QuickStartClient certificate, you will also need to export the certificate of the CA (which in this case is Root Agency, the sample CA).

To do this, double click on the WSE2QuickStartClient certificate in the MMC console. Go to the Certification Path tab and double click on the Root Agency certificate. In this new dialog, click on the Details tab and click on the Copy To File button.

Again, select Base 64 CER and save the file as c:\wssinterop\jwsdp14\certs\wse2ca.cer

To import these certificates into the JKS, open a command prompt to the c:\wssinterop\jwsdp14\certs directory and use the following commands:

keytool -import -file wseclient.cer -alias wse2client -keystore server-keystore.jks
keytool -import -file wse2ca.cer -keystore server-truststore.jks -alias wse2ca

(Enter the password for the JKS – changeit – when prompted).

With this public part of the certificate imported, setup of the JKS is now complete.

A word of caution: If you are not using the certificate supplied with the Sun JWSDP 1.4 sample, and you are looking to generate your own test certificates, keytool (the default tool for creating, import and exporting certificates) cannot be used. The JWSDP requires X509 v3 certificates for signing and encrypting. The keytool utility only creates X509 v1 certificates.

To overcome this, Sun supply a tool called pkcs12import that ships with JWSDP 1.4. This can be used with a .p12 (PKCS#12) key pair to import into an existing key store.

Installing a JCE RSA Provider

With the JKS correctly configured, you need to install a JCE provider for RSA. By default, Sun's JDK 1.4.2 does not ship with a JCE provider for RSA. As some of the certificates use RSA algorithms, you will need to download and install a third party provider.

In their documentation, Sun recommend going to the following URL which lists providers that offer this support: http://java.sun.com/products/jce/jce14_providers.html

Once downloaded, copy the provider JAR file to %JAVA_HOME%/jre/lib/ext/.

Modify the %JAVA_HOME%/jre/lib/security/java.security properties file and add the new JCE provider. The java.security file contains a list of security providers in the following format:

security.provider.<n>=<provider class name> 

Add the new JCE provider in position 2, making sure that the Sun security provider remains at the highest preference, with a value of 1. You may have to adjust the levels of the other security providers downward so that there is only one security provider at each level.

The sample code associated with this article has been tested against the "Legion of the Bouncy Castle" JCE provider. For reference, the java.security file was configured as follows with this installation.

security.provider.1=sun.security.provider.Sun
security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.rsajca.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider

Further information on this configuration can be found at: http://java.sun.com/webservices/docs/1.4/tutorial/doc/XWS-Security4.html#wp520663

Configuring Tomcat 5.0 to Use the JKS

With the JKS configured and the RSA security provider installed, one of the final steps is to tell the Tomcat installation where to find the JKS file.

To do this, you need to enable the SSL connector in Tomcat. Although you won't be using SSL to communicate with the Web services sample, this port is required to secure the connection between the Tomcat server and the JKS file that holds the keys and certificates.

Stop the Tomcat server (if running) and open the c:\tomcat-jwsdp-1.4\conf\server.xml configuration file.

Locate the connector port for 8443 (the default SSL port for Tomcat). This section will likely be commented out. Uncomment the connector and add the location of the keystore file and password using the keystoreFile, keystorePass, truststoreFile and truststorePass attributes.

Your connector should then look similar to this if using the defaults of this article:

<Connector port="8443" 
         maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
         enableLookups="false" disableUploadTimeout="true"
         acceptCount="100" debug="0" scheme="https" secure="true"
         clientAuth="false" sslProtocol="TLS"
         keystoreFile="/wssinterop/jwsdp14/certs/server-keystore.jks"
         keystorePass="changeit"
   truststoreFile="/wssinterop/jwsdp14/certs/server-      truststore.jks"
      truststorePass="changeit"
/>

Save the file when complete.

Enabling WS-Security and Rebuilding the Service

The final step in this process is to enable WS-Security for the JWSDP project. To do this, navigate to C:\WSSInterop\jwsdp14\wsdp\service\OrderService and open the targets.xml file.

Locate the generate-sei-service target and insert the following line in to the parameters list:

-security ${server.security.config}

Your target should look as follows:

  <target name="generate-sei-service"
      description="Runs wscompile to generate the model file">
    <antcall target="run-wscompile">
      <param name="param1" value="-define -d ${build} -nd ${build} -f:documentliteral
      -classpath ${build} ${config.interface.file} 
      -model ${build}/${model.file}
-security ${server.security.config}"
      />
    </antcall>
   </target>

With this done, run the build.bat file and restart the Tomcat server. As Tomcat is starting, watch the logs to ensure that there are no errors during startup.

Using X509 to Sign Messages

With the X509 certificate stores and keys correctly configured you are in a position to sign and encrypt requests.

Signing Messages (WSE 2.0 to JWSDP 1.4)

As mentioned previously in the article, signing a request using WSE 2.0 can be performed either in code or by using a policy file. For these samples, we'll be showing how this can be done using a policy.

Creating a policy file can be done manually (after all, they are just XML files) or by using the WSE 2.0 Configuration Tool. The configuration tool offers a wizard-like interface.

Accessing the configuration tool is performed through Visual Studio .NET 2003 by right clicking on the Client project and selecting the WSE Settings 2.0. . . menu item. If you do not have Visual Studio .NET 2003 installed, you can also run this command from the command line:

C:\Program Files\Microsoft WSE\v2.0\Tools\ConfigEditor\WseConfigEditor2.exe

Note: If you run the tool from the command line, you'll need to open the app.config file from c:\wssinterop\jwsdp14\dotnet\client.

The configuration tool offers many settings for Security, Routing, Filters, Policy, Token Issuing and Diagnostics, as shown in Figure 6.

ms954606.interopsun-06(en-us,MSDN.10).gif

Figure 6. The WSE 2.0 Configuration Tool

Navigate to the Policy tab shown in Figure 7.

ms954606.interopsun-07(en-us,MSDN.10).gif

Figure 7. The Policy Tab of the Configuration Tool

To enable policy for this application, click on the Enable Policy check box. A path to the policyCache.config file (../../policyCache.config) will be displayed.

Click on the Add button. In the Endpoint URI field enter a value of http://localhost:8080/OrderService/OrderService (make sure that the port used in this URL corresponds to the port number being used by Tomcat – 8080 is the default). This is the endpoint URL for the Sun JWSDP 1.4 Service.

Click on OK. The WSE Security Setting wizard will be launched. Click on Next to start the wizard and Next to select the option to secure a client application.

The next screen of the wizard displays information for the type of operation we wish to perform.

ms954606.interopsun-08(en-us,MSDN.10).gif

Figure 8. Configuring Security using the WS-Security Settings Wizard

As shown in Figure 8, using the wizard you have the option of specifying to sign and encrypt request and response messages.

For the sample here, select the Require signatures checkbox in the request message (and ensure that Require encryption is unselected on the response message). This will configure WSE 2.0 to sign outbound requests for this application.

In the next stage of the wizard choose the token type (select X509 Certificate). You will then be asked to select a certificate. As we are signing the message – which requires access to our private key—we need to use the certificate on the client (WSE2QuickStartClient certificate). In the select certificate window ensure that this certificate is correctly selected:

ms954606.interopsun-09(en-us,MSDN.10).gif

Figure 9. Selecting the Certificate to Sign the Request

Click on Next to validate your selection and Finish to complete the wizard. The policy file has been created, which specifies that your client should sign the Web Service.

With this new policy in place, re-run the client application. The client will call the Web Service as before, except this time the request to the JWSDP Web Service will be signed. You can validate this by investigating the SOAP trace for the request. You can see this in the webinfo WSE trace files or the Tomcat console.

If you look at the trace for the message you will see that it includes a binary security token, a list of signing capabilities, a signature value and a security token reference.

The binary security token is the public X509 certificate (which is used to validate the authenticity of the signature):

<wsse:BinarySecurityToken ValueType=http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3
EncodingType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
soap-message-security-1.0#Base64Binary
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-6bc048f9-1ff9-407c-
9c5b-440c6067088c">MIIBxDCC. . .
(this part snipped for this article). . .R8ajJfl</wsse:BinarySecurityToken>

The signature value is the signed hash of the message.

<SignatureValue>NEsW7+HcG4sIxGfoVEF1s+1DUtacoPIY4iCj1qg8eHn2znkVle80p4f
wBwXFfghchmnNlf5QF1Dt/Bte8pee2wWHGA34s8FidO9a3YjGDL1Vg+2Ed0baNOtUPYFliS
czK5dpz2rk/Aan65zD7ngjhQja9gnsierojrluug2b8EQ=</SignatureValue>

Signing the Response

You've seen how you can use WSE 2.0 to sign a message using an X509 certificate. If you observed the SOAP trace, you will have however noticed that the response from the server was unsigned. We can enable signing on the response by configuring the JWSDP Web Service.

To do this, navigate to the c:\wssinterop\jwsdp14\wsdp\service\OrderService\config directory. In here you will find a wsse.xml file. This is a configuration file used to set the WS-Security options for outbound server responses.

Open the file and uncomment the line that reads:

<xwss:Sign senderCertificateAlias="s1as"/>

This line instructs the Web Service to sign the response to the client. The certificate used is s1as, which as you may remember is the alias that contains both the private and public key in the keystore (s1as is the JKS alias for xws-security-server).

After you uncomment this line, re-build the solution and redeploy to the Tomcat installation. For this you will need to stop the Tomcat server, re-run the build.bat batch file in the OrderService directory and restart the server.

Once complete, re-run the sample. In the SOAP trace you should now see that the response from the JWSDP Web Service is signed –in the same way as the request was, except using the server certificate.

Using X509 to Encrypt Messages

Signing is useful for verifying the integrity of the message and the authenticity of the sender. In the example X509 signing can be used to verify that the credit card details and tracking number were not altered in transit, and to guarantee the identity of the sender. The sample code for both WSE 2.0 and Sun JWSDP 1.4 can be modified to allow authorization based on this signature.

This is useful in understanding the integrity of the message (after all it's not desirable to have the details modified), but for sending credit card details between the machine we may also wish to also encrypt the data. This will prevent anyone who has access to the message being able to read the credit card data directly.

Encrypting Messages from WSE 2.0 to JWSDP 1.4

To configure the client in WSE 2.0 to encrypt messages to the Sun JWSDP 1.4 Web Service we can again use the configuration tool.

Open the tool (by right clicking on the project in Visual Studio .NET 2003 and selecting WSE 2.0 Settings from the menu) and navigate to the policy tab. Replace the existing policy for http://localhost:8080/OrderService/OrderService.

Navigate through the wizard, just as you did with the signing example previously, but this time select Require Encryption for the request message as shown in Figure 10 This policy states that the client will encrypt the data of the request.

ms954606.interopsun-10(en-us,MSDN.10).gif

Figure 10. Selecting option to Require Encryption

When selecting the certificate, choose the JWSDP 1.4 server side certificate (xws-security-server), as seen in Figure 11.

ms954606.interopsun-11(en-us,MSDN.10).gif

Figure 11. Selecting the Certificate used by the JWSDP 1.4 Service

The WSE 2.0 client uses the public key of the server's certificate to encrypt the data. When the server receives the encrypted message it will use the corresponding private key to decrypt the request.

Complete the wizard and re-run the sample. After the client successfully sends the message, look at the trace to investigate the message that was sent.

What you will observe is that the body of the SOAP message contains the encrypted data for the call:

<soap:Body><xenc:EncryptedData Id="EncryptedContent-e0f66417-e3dd-4f80-
b340-5e52f154efd1" Type="http://www.w3.org/2001/04/xmlenc#Content" 
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod 
Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" 
/><xenc:CipherData><xenc:CipherValue>io4Xnvc66EAFd0mnXzngnTIuS9Ej3/gd2M
RCnYRi348a1XRRVBS50eKYm+SZB55HwYbd02/JTgQLTrQKi1FS5NavpyDJj/1E0D9Hkgosy
6WBuyXElPFXBBYsQUyODGcukAz5CTXreDQqfsTAbGy9NIXUKgJcOA0WPwhVTh1vE19oc8x8
5ir59fglOxBmcGzQMKsLy/9SPuR5Ma6Blg5r9pFlHq9mrElH/1KwfQWyRU5LG37wUFV8VhG
6+5QvxYIq1dwDe8tTDMxVLW+VsCKCpqUgSz7ZQdaY7ncKwBcMniDIpoIAjaXB70m/igEJE+
0vLZQClAHMpFg=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData
></soap:Body>

Remember before encryption was enabled, the SOAP body looked like this, showing the credit card details in clear text:

<soap:Body>
<submitOrder xmlns="http://wss.samples.microsoft.com">
<OrderImpl_1 xmlns="">
<id>348922</id>
<creditCardNum>4426-1234-5678-9012</creditCardNum>
<creditCardExpM>10</creditCardExpM>
<creditCardExpY>5</creditCardExpY>
</OrderImpl_1>
</submitOrder>
</soap:Body>

One important thing to notice in the encrypted message is the algorithm used for encryption. In this example, the encryption is being performed using a 3DES session key:

<xenc:EncryptionMethod 
Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />

The default encryption algorithm for WSE 2.0 is Rijndael AES128. Sun JWSDP only supports the 3DES algorithm for encryption in v1.4. To overcome this, the following line in the app.config file forces WSE 2.0 to use 3DES instead:

<binarySecurityTokenManager valueType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
        <sessionKeyAlgorithm name="TripleDES" />
      </binarySecurityTokenManager>

This provides a way of encrypting messages from WSE 2.0 to Sun JWSDP 1.4 that is interoperable between the two.

Encrypting the Response

The final piece of this X509 sample is to show how the client encrypts the response sent back to the client. For Sun JWSDP 1.4 enabling this is done in a similar way to signing.

Edit the wsse.xml file in the C:\WSSInterop\JWSDP14\wsdp\service\OrderService\config directory. Comment out the xwss:Sign element and uncomment the xwss:Encrypt element:

<xwss:Encrypt receiverCertificateAlias="wse2client">

Ensure that the alias of the certificate reads wse2client, which corresponds to the public portion of the WSE2QuickStartClient in the JKS.

After you uncomment this line, re-build the solution and redeploy to the Tomcat installation. For this you will need to stop the Tomcat server, re-run the build.bat batch file in the OrderService directory and restart the server.

Once complete, re-run the sample. In the SOAP trace you should see that the response from the JWSDP Web Service is encrypted#&151;much the same way as the request was.

Conclusion

In this article you have seen the basics of how to use Microsoft WSE 2.0 and Sun JWSDP 1.4 to sign and encrypt Web services calls. This was performed using X509 certificates and OASIS WSS 1.0.

As a standard, WS-Security is still new. The capability to use WS-Security to perform vendor neutral, transport independent security for Web services is however powerful. The commitment of all vendors, with the OASIS specification proves that security for Web services is achievable today.

Thanks to Keith Ballinger, Kirill Gavrylyuk, HongMei Ge, Jason Hogg, Byung Chan Kim, Vick Mukherjee, and Anita Jindal (Sun Microsystems) for their valuable input into this article.

 

About the author

Simon Guest is a Program Manager in the Architecture Strategy team at Microsoft Corporation, and specializes in interoperability and integration. Simon holds a Masters Degree in IT Security from the University of Westminster, London, and is the author of the Microsoft .NET and J2EE Toolkit (Microsoft Press, Sept. 2003).

Simon can be reached via his blog at http://www.simonguest.com.

Show:
© 2014 Microsoft