XML.com 
 Published on XML.com http://www.xml.com/pub/a/ws/2003/01/15/ends.html
See this if you're having trouble printing code examples

 

Securing Web Services
By Rich Salz
January 15, 2003

What's the Need?

According to the conventional wisdom, web services will not be successful until they're "secure." Without discussing the accuracy of the claim, let's look at what it means. In the web services context security means that a message recipient will be able to do some or all of the following:

In a distributed environment -- really, any time you have more than a single program running under a local operating system -- these requirements are met by using cryptography. Two of the most fundamental operations, signing and encrypting, can directly meet the first two needs. The other two requirements, and all the supporting infrastructure that they need, are built on top of those operations.

Related Reading

Programming Web  Services with SOAP

Programming Web Services with SOAP
By James Snell, Doug Tidwell, Pavel Kulchenko

Table of Contents
Index
Sample Chapter

Read Online--Safari Search this book on Safari:
 

Code Fragments only

How High the Stack?

There is a lot of security-related activities occurring at the various standards organizations. I think these are the most important right now:

In addition, the Web Services Interoperability Organization is defining a security profile to ensure basic interoperability among vendors. IBM and Microsoft, along with various partners, have issued a Security Roadmap that includes six -- SIX! -- new specifications.

All of that is almost enough to make you long for the days of ISO and X.400 specifications. Fortunately, we don't have to wait for the full suite; we can get real work done and solve real problems right now.

Why not SSL?

Let's look at the work involved in protecting a SOAP message. The obvious first question is why SSL isn't good enough. When Netscape turned SSL over to the IETF, they named the working group Transport-Level Security for good reason.

First, SSL operates between communication endpoints, not between applications. That's fine for most of the human-consumable Web, where a user is directing a browser to a web site. But even that falls down in the simple case of CGI scripts -- bugs in the web server (hard to imagine, I know) could result in undetected corruption of the POSTed data. Inexperienced ISPs often seem to have trouble setting up their first multihomed, multi-identity web server. In order to have different SSL server certificates, they must have different network endpoints, which often means either listening on different ports or configuring their network interface to "alias" multiple addresses.

There is also a more subtle, cryptographic point. When using SSL/TLS, you can't save the message for later to prove that it hasn't been modified. First, you have to save the entire two-way byte stream and "replay" the SSL traffic to get the plain text. Even if that were feasible, the fundamental architecture of SSL/TLS makes it impossible.

When a connection is established, parties exchange a transient session key to encrypt the data between them. Both parties have the same key, but it's only intended to be used for a short period of time. In case of a dispute, it's impossible for either party to prove that it has the unmodified message. As the saying goes, two people can keep a secret, but only if one of them is dead.

Since SSL/TLS isn't appropriate, we need other mechanisms. We need something that sits at the same layer as the message, something that's part of the SOAP message itself. Lucky for us, SOAP headers fit nicely with detached signatures to make this possible.

Signature Types

XML DSIG supports three signature types and each has its use:

An enveloped signature is useful when you have a simple XML document which you to guarantee the integrity of. For example, XKMS messages can use enveloped signatures to convey "trustable" answers from a server back to a client. An enveloping signature is useful when the signing facility wants to add its own metadata (such as a timestamp) to a signature -- it doesn't have to modify the source document, but can include additional data covered by the signature within the signature document it generates. (An XMLDSIG signature can sign multiple objects at once, so enveloping is usually combined with another format.)

A detached signature is useful when you can't modify the source; the downside is that it requires two XML documents -- the source and its signature -- to be carried together. In other words, it requires a packaging format -- enter SOAP headers.

WS-Security

WS-Security specifies how to sign and encrypt SOAP messages. At the simplest level, it says to put the XML DSIG signature in a SOAP Header element with a specific qname:

<SOAP:Envelope xmlns:SOAP='http://schemas.xmlsoap.org/soap/envelope/'>
  <SOAP:Header>
    <wsse:Security xmlns:wsse='http://schemas.xmlsoap.org/ws/2002/07/secext'>
      <Signature xmlns='http://www.w3.org/2000/09/xmldsig#'>
        ...defined below...
      </Signature>
    </wsse:Security>
  </SOAP:Header>
  <SOAP:Body id='Body'>
      ...message body...
  </SOAP:Body>
</SOAP:Envelope>

Unfortunately WS-Security only allows one instance of this header, making multiparty signatures (imagine an online auction with buyer, seller, and auctioneer) a little awkward. Nevertheless, if I want to keep the tamper-evident proof for my application message, I only have to keep the SOAP message, which is a much more tractable problem than saving an entire SSL/TLS transaction.

The Signature itself contains three parts: a reference to what is being signed (there can be multiple references), a signature value that covers the references, and information about the signing keys.

The SignedInfo element mainly contains references to data, a description of how to process and generate a hash for it, and what that hash (or more accurately, message digest) value is.

<SignedInfo>
  <CanonicalizationMethod Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'/>
  <SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>
  <Reference URI='#Body'>
    <Transforms>
      <Transform Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'/>
    </Transforms> <DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>
    <DigestValue>riJUygbyupbDqcIiV+jgIdHe7WQ=</DigestValue>
  </Reference>
</SignedInfo>

Without getting into too many details, this fragment says that the signed data is canonicalized and then hashed and signed with an RSA key. The node with a "Body" ID attribute is XML data that is canonicalized and has the specified hash value.

The signature value itself is a hash of the SignedInfo element and is fairly boring. It's important to realize, however, that XML DSIG gains its flexibility by always doing an indirection; the data itself isn't signed, a reference that specifies the data's digest is.

<SignatureValue>fHP...ZOA=</SignatureValue>

Finally we have information about the key that generated the signature. In this case it's an X.509 digital certificate.

<KeyInfo>
  <X509Data>
    <X509Certificate>MII...AABvi</X509Certificate>
  </X509Data>
</KeyInfo>

Where Are We?

We've done a lot of work; more accurately, we've looked at a lot of complicated XML. All we've done is guaranteed that the SOAP message that we have in hand is exactly the same message that someone sent. We haven't even started trying to answer any of the other important questions, such as who that entity is, whether we should trust them, and whether their claimed identity is still valid. Perhaps all those standards groups are really necessary after all?

XML.com Copyright © 1998-2006 O'Reilly Media, Inc.