Export (0) Print
Expand All
Expand Minimize

Web Services Security Interoperability Using Web Services Enhancement 2.0 and Systinet Server 5.0 for Java

 

Simon Guest
Microsoft Corporation

Hrudaya Alaparti Sruti, Nilesh Jain
Tata Consultancy Services

March 2005

Applies to:

   Microsoft .NET Framework 1.1
   Microsoft Visual Studio .NET 2003
   Microsoft Web Services Enhancements (WSE) 2.0 SP1
   Systinet Server for Java 5.0

Summary: This article shows Interoperability based on OASIS WS-Security 1.0 between Microsoft WSE 2.0 and Systinet Server for Java 5.0. 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. (24 printed pages)

Source Download:

Click here to download the source code for this article.


Contents

Required Software and Skills to Run the Code Samples
What Is WS-Security?
Installing and Configuring the Sample Code
Configuring WS-Security for Both WSE 2.0 and Systinet Server
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?

Web Services 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, and submitted to OASIS for ratification.

On April 6th 2004, OASIS 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 now starting to provide implementations of WS-Security. Microsoft offers OASIS WS-Security 1.0 support in WSE (Web Services Enhancements) 2.0, a download from MSDN that compliments the Web services support in the .NET Framework. Systinet offers Server for Java 5.0 along with the Web services security framework, which can be downloaded from their site.

This article covers techniques to send secure messages between the Microsoft .NET Framework and J2SE using Microsoft WSE 2.0 and Systinet Server for Java 5.0, 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 TCP

    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 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 may not be an option. For non-TCP transports, 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 securing 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 in 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 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 Systinet Server for Java 5.0, 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\systinet. 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.

Click here for larger image.

Figure 1. The WSE 2.0 SP1 installation wizard (click the graphic for a larger image)

Installing and Configuring Systinet Server 5.0 for Java

You can install Systinet Server for Java 5.0 from the download site, which can be found here.

The download is a JAR file. To install, run the following command from the command prompt (in the directory containing the JAR file):

java -classpath wasp-java-5.0.jar Install

After running the command, the screen as shown in Figure 2 appears.

Click here for larger image.

Figure 2. The Systinet installation wizard (click the graphic for a larger image)

When proceeding through the installation wizard, on the screen for Select Install Type, select the Install Security Support option as shown in Figure 3. This will ensure that the required security libraries are installed correctly.

Click here for larger image.

Figure 3. Installing WS-Security support for Systinet (click the graphic for a larger image)

Note that for all future references in this article, WASP_HOME refers to the directory where the Server for Java has been installed (for example, C:\Program Files\wasp50).

For the System requirement and installation details for Systinet Server for Java 5.0, please refer to Installation and Porting Guide in the Product Documentation.

With Systinet Server for Java 5.0 and Microsoft WSE 2.0 successfully installed, let's now take a look at the Sample Web service.

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 result will look similar to the one shown in Figure 4.

ms998278.wssisystinet-04(en-us,MSDN.10).gif

Figure 4. Overview of the sample Web service

As previously shown, the operation is fairly simple; 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 representative of the data that will be sent on the wire.

The XSD file, which can be found in the c:\wssinterop\systinet\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 in the code, 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. Similarly, Schema2Java.bat is a part of the Systinet Server for Java 5.0 and can be found in WASP_HOME\bin directory. This is used to generate the Java file from the XSD document.

Building the Systinet Web Service

To help build the schemas and the Web service, you can use a batch file called run.bat, located in the c:\wssinterop\systinet\service directory. This is similar to how other samples supplied with Systinet Server have been configured.

The first task is to take the XSD file described in the previous section and generate platform (Java) specific classes. To do this, from a command prompt, run the following from the c:\wssinterop\systinet\service directory:

run MAKE_SCHEMA

This uses the Schema2Java tool within Systinet Server to generate the Java file (Order.java) from the XSD document. This generated class looks as follows:

/**
 *
 */
public class Order {


    protected long Id;
    public long getId() { return Id; }
    public void setId(long Id) { this.Id = Id; }

    protected java.lang.String CreditCardNum;
    public java.lang.String getCreditCardNum() { return CreditCardNum; }
    public void setCreditCardNum(java.
lang.String CreditCardNum) { this.CreditCardNum = CreditCardNum; }

    protected java.lang.Integer CreditCardExpM;
    public java.lang.Integer getCreditCardExpM() { return CreditCardExpM; }
    public void setCreditCardExpM(java.
lang.Integer CreditCardExpM) { this.CreditCardExpM = CreditCardExpM; }

    protected java.lang.Integer CreditCardExpY;
    public java.lang.Integer getCreditCardExpY() { return CreditCardExpY; }
    public void setCreditCardExpY(java.
lang.Integer CreditCardExpY) { this.CreditCardExpY = CreditCardExpY; }


}

/*
 * Generated by Systinet WSDL2Java
 * http://www.systinet.com
 */ 

After this is complete, you can now compile the server classes. This can be done by using the run.bat file with the MAKE_SERVER parameter:

run MAKE_SERVER

With the classes generated and the source compiled, we can now start the server and publish the underlying OrderService class. Use the run.bat file with the RUN_SERVER parameter to start this.

run RUN_SERVER

If everything is successful, the Systinet Server will start and the Order Web service will be published. You will see startup messages similar to:

INFO: log4j.Log4JAdapter-Events Log File: c:/Program Files/wasp50/log/logEvents.log
INFO: log4j.Log4JAdapter-Error Events Log File: c:/Program Files/wasp50/log/errorEvents.log
Service is published on: /com/microsoft/samples/wss/OrderService
Server is running...

Building the Client

Now that the Systinet Server is running, you can build and run the client.

Before building the client you need to create the proxy for the deployed Systinet Web service. To do this, navigate to the c:\wssinterop\systinet\dotnet\client\proxy directory and run generate.bat. This batch file calls wsewsdl2.exe to generate a proxy file (OrderProxy.cs) from the Systinet server running in the background.

After the proxy has been generated, open OrderProxy.cs in either Visual Studio .NET or your text editor of choice. Locate the following line:

public class OrderService : System.Web.Services.Protocols.SoapHttpClientProtocol

Replace the inherited class (SoapHttpClientProtocol) with this:

public class OrderService : Microsoft.Web.Services2.WebServicesClientProtocol

Doing this will ensure that the WSE network stack is used, required for both tracing and the security options that we'll be using in this article.

You can build and run the client through Microsoft Visual Studio 2003 or by using the command line. If you have Visual Studio .NET 2003 installed, open the WSS.sln solution in the C:\wssinterop\systinet\dotnet directory to build and run the client. If you do not have Visual Studio .NET 2003, you can use the build.bat file in the Client sub-directory. Run the Client.exe file to run the client.

On running the client you should observe the following:

Creating order...
Sending payment information to SSJ Web Service...
Submit complete.  The tracking number for this order is: 405615979

Press Enter to continue.

As shown, the order is created and sent to the Systinet Web service. On completion, a tracking number is returned to the client (this is a randomly generated number, so yours will likely be different).

If you switch to the Systinet Web service (running in a separate command window), you should see the following:

Credit Card information has been received by Systinet Server for Java Web Service
Order: 348922
Credit Card Information: 4426-1234-5678-9012 Expiry: 10/05

Congratulations! The Web service is now working correctly! Let us 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 set up. 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 Systinet Web service.

For WSE 2.0, all messages are written to the InputTrace.webinfo and OutputTrace.webinfo files in the c:\wssinterop\systinet\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.

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

    <soap:Body>
      <p0>
        <creditCardExpM>>10</creditCardExpM>
        <creditCardExpY>5</creditCardExpY>
        <creditCardNum>4426-1234-5678-9012</creditCardNum>
        <id>348922</id>
      </p0>
    </soap:Body>

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

    <e:Body>
      <wn1:int_Response>1142590053</wn1:int_Response>
    </e:Body>

You can also use a trace tool to investigate this graphically. The WseTrace tool can display these correlated messages in a UI, as shown in Figure 5.

Click here for larger image.

Figure 5. WseTrace provides a graphical view of the WSE 2.0 trace files (click the graphic for a larger image)

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

Configuring WS-Security for Both WSE 2.0 and Systinet Server

WSE 2.0 and Systinet 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 .NET client, we will be using WS-Policy to enable WS-Security. As WS-Policy is not yet supported within the version of Systinet Server shown here, the WS-Security features for the Java Web service will be set programmatically.

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 Systinet and from Systinet to WSE 2.0), you need to set up some certificates and keys. For this sample, a combination of the keys and certificates provided in both the Microsoft WSE 2.0 and a custom certificate created for Systinet 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:

ms998278.wssisystinet-06(en-us,MSDN.10).gif

Figure 6. 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 Systinet (PK2). The Systinet 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 Systinet Web service, it uses the private key (pK1) to generate a signed hash of the message (this can be represented as SpK1(M)). The public key is also be sent with the message to allow that the Systinet Web service to verify the signature (creating SpK1(M),PK1).

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

These operations work in reverse when the Systinet 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 Systinet, the Protected Store (also known as PStore) is used.

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 export the certificate required for the Systinet service. 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 FileAdd/Remove snap-in, click Add, 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 7.

Click here for larger image.

Figure 7. MMC view of the certificate store (click the graphic for a larger image)

To export the WSE client certificate, right click on the WSE2QuickStartClient and select All TasksExport. 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\systinet\certs\client.cer.

Configuring Certificates for the Systinet Service

The Systinet Web service uses the PStore to access X509 certificates and corresponding private keys. To import the required certificates into this store, the following actions need to be done:

Ensure that the Systinet service is running, and open a command prompt and navigate to the C:\wssinterop\systinet\service directory.

Execute the run.bat file with the CREATE_IDENTITIES parameter:

run CREATE_IDENTITIES admin changeit

Note   admin and changeit are the default username and password for the service providers on the Systinet server. You are free to choose your own; however, you will need to change the sample source code accordingly.

This command will create the certificate and the corresponding private key (DemoOrderSecurityService) in the PStore. It will also export the certificate service.cer to the c:\wssinterop\systinet\certs directory.

Completing the Import for the Microsoft Client

The final step is to import the service.cer file into the Windows store. To do this, double click on the server.cer file (in the c:\wssinterop\systinet\certs directory) from within Windows Explorer.

In the certificate dialog window, click on the Install Certificate button, select the Personal store, and import the certificate. Repeat this process, selecting this time the Trusted Root Certification Authorities store.

(The certificate needs to be in the Personal store for selecting it to encrypt data for the Systinet Web service and in the Trusted Root Certification Authorities store for validation—as it is self signed. This is a temporary option for running this sample, and you should remove the certificate from the Trusted Root list as soon as you are done).

With this complete, we can now enable WS-Security between the two platforms.

Enabling WS-Security and Rebuilding the Service

To enable WS-Security for the Systinet service, open the BaseService.java file. This is located in the c:\wssinterop\systinet\service\src\com\microsoft\samples\wss directory.

In the validate method, locate the following two sections:

   // uncomment this section to enforce signing
/*        if (!bodySigned) {
            throw new WSSecurityException(Constants.
ERROR_INVALID_SECURITY, "SOAP Body needs to be signed");
        }
*/
   // uncomment this section to enforce encryption
/*        if (!bodyEncrypted) {
            throw new WSSecurityException(Constants.
ERROR_INVALID_SECURITY, "SOAP Body must be encrypted");
        }
*/

These two if statements enforce both signing and encryption from the WSE 2.0 client. Uncomment the if (!bodySigned) code block. This will require that all incoming messages from the WSE 2.0 client are signed.

After saving the file, stop the Systinet Service if it is running in the background. Navigate to the c:\wssinterop\systinet\service folder and run the following two commands to rebuild and re-run the service:

run MAKE_SERVER
run RUN_SERVER

The secured Systinet service is now running. Now we can start configuring the WSE 2.0 client to sign the messages.

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 Systinet)

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\systinet\dotnet\client.

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

Click here for larger image.

Figure 8. The WSE 2.0 configuration tool (click the graphic for a larger image)

Navigate to the Policy tab shown in Figure 9.

Click here for larger image.

Figure 9. The Policy tab of the configuration tool (click the graphic for a larger image)

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:6060/com/microsoft/samples/wss/OrderService. This is the endpoint URL for the Systinet service.

Click OK. The WSE Security Settings 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.

Click here for larger image.

Figure 10. Configuring Security using the WS-Security Settings wizard (click the graphic for a larger image)

As shown in Figure 8, using the wizard gives you 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 (the WSE2QuickStartClient certificate). In the select certificate window ensure that this certificate is correctly selected:

ms998278.wssisystinet-11(en-us,MSDN.10).gif

Figure 11. 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 Systinet 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-d517448a-01f3-4c0c-99af-
9392cedd47b4">MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQ
FADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5
NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA
4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY
5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg
7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5Akt
Bh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcN
fQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sS
dWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl</wsse:BinarySecurityToken>

The signature value is the signed hash of the message.

<SignatureValue>W4uslkiQCa0DUsp2X56qLdU1tX6sTDQ4jeP4pGL0AKJBRL/HDL5vwxNW
eR75XT9r2pVc0qRFbfyFoJeHVHFbcrZgkW0zZGGQSFDIvZQrm/216m/ED7Yev9A9r1B0mtJP
cHT9HLKC7SZwdkH5Oz+raA5osi/G+8XG/1wWNKiVh6o=</SignatureValue>

Signing the Response

You've seen how you can use WSE 2.0 to sign a message using an X509 certificate. If you observe the SOAP trace, you will notice, however, that the response from the server is unsigned. We can enable signing on the response by editing and re-running the Systinet service.

To do this, navigate to the C:\wssinterop\systinet\service\src\com\microsoft\samples\wss directory and edit the OrderServiceImpl.java file.

This file implements the required configureWSSecurity method that defines WS-Security properties for outgoing messages. The signing section can be found within:

// add X509 token
ReferencedToken x509ExternalToken = new ReferencedToken(new X509
Token(SERVER_IDENTITY, SERVER_IDENTITY_PASSWORD));
messageSecurity.addToken(x509ExternalToken);
messageSecurity.addExternalToken(x509ExternalToken);

// sign entire Body
Signature signature = new Signature(x509External
Token);      signature.setCanonicalizationMethod
(Constants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
signature.setSignBody();
messageSecurity.addSecurityElement(signature);

To enable this code, change the following line:

boolean sign = false;

Set a true value.

boolean sign = true;

Save the file. Ensuring that the service is stopped, run the following two commands from the c:\wssinterop\systinet\service directory:

run MAKE_SERVER
run RUN_SERVER

Re-run the WSE 2.0 client. Observing the trace file should now show that the response is signed.

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 Systinet service 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 encrypt the data. This will prevent anyone who has access to the message from being able to read the credit card data directly.

Encrypting Messages from WSE 2.0 to Systinet Server

To configure the client in WSE 2.0 to encrypt messages to the Systinet 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:6060/com/microsoft/samples/wss/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 12. This policy states that the client will encrypt the data of the request.

Click here for larger image.

Figure 12. Selecting option to Require Encryption (click the graphic for a larger image)

When selecting the certificate, choose the Systinet server side certificate (DemoOrderSecurityService), as seen in Figure 13.

ms998278.wssisystinet-13(en-us,MSDN.10).gif

Figure 13. Selecting the certificate used by the Systinet 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.

After completing the wizard, from a command prompt navigate to the C:\wssinterop\systinet\service\src\com\microsoft\samples\wss directory. We now need to configure the Systinet service to accept encrypted requests. In the BaseService.java file, comment the signing part and uncomment the encrypted part as seen here.

   // uncomment this section to enforce signing
/*        if (!bodySigned) {
            throw new WSSecurityException(Constants.
ERROR_INVALID_SECURITY, "SOAP Body needs to be signed");
        }
*/
   // uncomment this section to enforce encryption
        if (!bodyEncrypted) {
            throw new WSSecurityException(Constants.
ERROR_INVALID_SECURITY, "SOAP Body must be encrypted");
        }

Save the file. Ensuring that the service is stopped, run the following two commands from the c:\wssinterop\systinet\service directory:

run MAKE_SERVER
run RUN_SERVER

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/gd
2MRCnYRi348a1XRRVBS50eKYm+SZB55HwYbd02/JTgQLTrQKi1FS5NavpyDJj/1E0D9Hk
gosy6WBuyXElPFXBBYsQUyODGcukAz5CTXreDQqfsTAbGy9NIXUKgJcOA0WPwhVTh1vE1
9oc8x85ir59fglOxBmcGzQMKsLy/9SPuR5Ma6Blg5r9pFlHq9mrElH/1KwfQWyRU5LG37
wUFV8VhG6+5QvxYIq1dwDe8tTDMxVLW+VsCKCpqUgSz7ZQdaY7ncKwBcMniDIpoIAjaXB
70m/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>

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 the Systinet service, enabling this is done in a similar way to signing.

Navigate to the C:\wssinterop\systinet\service\src\com\microsoft\samples\wss directory and edit the OrderServiceImpl.java file.

As we saw in the signing section, this file implements the required configureWSSecurity method that defines WS-Security properties for outgoing messages. The encryption section can be found within:

// add token
KeyIdentifiedToken x509Token = new KeyIdentifiedToken(new X509Token(ENCRYPT_CERT_DN));
x509Token.setId("encrypt-cert");
messageSecurity.addToken(x509Token);

// encrypt body
EncryptedData encryptedData = new EncryptedData(x509Token);
encryptedData.setEncryptBody();
        encryptedData.setEncryptionMethod(Constants.ALGO_ID_BLOCKCIPHER_TRIPLEDES);
           encryptedData.setKeyEncryptionMethod(Constants.ALGO_ID_KEYTRANSPORT_RSA15);
messageSecurity.addSecurityElement(encryptedData);

To enable this code, change the following line:

boolean encrypt = false;

Set a true value.

boolean encrypt = true;

Save the file. Ensuring that the service is stopped, run the following two commands from the c:\wssinterop\systinet\service directory:

run MAKE_SERVER
run RUN_SERVER

Re-run the WSE 2.0 client. Observing the trace file should now show that the response is encrypted.

Conclusion

In this article you have seen the basics of how to use Microsoft WSE 2.0 and Systinet Server 5.0 for Java to sign and encrypt Web services calls. This was performed using X509 certificates and OASIS WS-Security 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, very powerful. The commitment of all vendorsto the OASIS specification proves that security for Web services is achievable today.

Thanks to Anurag Katre and Sarvashrestha Paliwal from Tata Consultancy Services, and Jan Alexander and Radovan Janecek from Systinet Corporation, 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 through his blog at http://www.simonguest.com.

Show:
© 2014 Microsoft