Xml Web Services and Soap
Background
So how do I get off claiming that there is no security in SOAP? HOW TO: Secure XML Web Services with SSL, Authentication and Authorization, and Building Secure Web Services with Microsoft SOAP Toolkit 2.0 are just a few articles on MSDN alone that tout the security of SOAP. The key point to realize is that these articles mostly speak of HTTP security and not SOAP security. Relying on transport-level security can have its benefits, particularly when the infrastructure for the transport is as widespread as it is in the case of HTTP. Very secure applications can be created based upon the underlying transport security mechanisms—but there are limitations to what HTTP can provide to a SOAP application.
SOAP is a message format and is not tied to a single protocol. If you rely on HTTP to perform the authentication for your XML Web Service, then you restrict yourself to that protocol. It is conceivable, however, that a single SOAP message could be routed over a number of protocols. Similarly, it may make sense that a message is encrypted in such a manner that no one can read the message between the sender and the final receiver. If you use the standard mechanism for encrypted SOAP today, which is to send a message using HTTP over SSL, then each node along your SOAP message's route will be able to read your data—obviously not the desired result.
But now we can ring the church bells in celebration of SOAP security, because Microsoft has made a proposal for standardized SOAP Security as part of their Global XML Web Services Architecture. The new standard will allow for passing authentication credentials, insuring message integrity, and allowing for message privacy—all within the SOAP messaging schema.
Keys, Encryption, Signatures, and Certificates
Before we dig into SOAP Security, let's talk about some fundamental security concepts. We'll start with encryption schemes. There are two common categories of encryption schemes, both involving keys.
- Symmetric encryption schemes use the same key to both encrypt and decrypt a message. A symmetric key is often called a session key.
- Asymmetric encryption schemes have two different keys: a public key and a private key. A message encrypted with a public key can be decrypted with the private key. A message encrypted with the private key can be decrypted with the public key. Private/Public key encryption mechanisms provide a lot of power for performing authentication and insuring data integrity.
A couple of other terms you should be familiar with: A hash is an algorithm that takes any data as input and creates a fixed length output. A digest is a hash with a couple other features. First, the algorithm for creating a digest must be such that it is statistically improbable for the results of one input to match the results of a different input. Secondly, it must be impossible to determine the input given the output.
Okay, now let's consider the case where Bob computes a digest for a message, then encrypts his digest with his private key. Bob then sends the message to Alice along with the encrypted digest. Alice wonders if some evil person got a hold of the message and tampered with its contents. First of all, Alice decrypts the digest using Bob's public key. She then uses the same digest algorithm that Bob used on the message. If it matches the decrypted digest, she knows that 1) the message has not changed since Bob computed his digest, and 2) no one else but Bob could have encrypted the digest, since his public key was able to decrypt it. Bob's encrypted digest is called a digital signature.
A certificate is the standard way to pass around public or symmetric keys. The message format for a certificate includes a digital signature from a Certificate Authority. Trusting a Certificate Authority in effect means you trust that any certificates created by that authority properly identify the owner for whom the certificate was issued. Therefore the private key that corresponds to the public key in the certificate is deemed to be known only by the specified owner. The most common way for representing certificates is to use a standard format referred to as X.509.
XML Signatures
The Web Services Security Language draft that defines security mechanisms for SOAP messages relies heavily on work done for XML messages in general. The XML-Signature Syntax and Processing proposed recommendation by the World Wide Web Consortium (W3C) defines a mechanism for creating and verifying digital signatures for all or part of an XML message. It also indicates an XML-compliant mechanism for holding a digital signature within an XML document.
Consider the following XML document for placing an order from Bob's Pencil Manufacturing Company.
<bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> </bp:pencilOrder>
If a customer, Alice's Retail Office Supply, sent this order to Bob's Pencil Manufacturing, how would the people at Bob's Pencil Manufacturing know that it came from Alice's Retail Office Supply?
One solution is for Alice's Retail Office Supply to first digitally sign the above XML document. Using the W3C XML-signature syntax, the above document signed by Alice's Retail Office Supply might look like this:
<bp:signedPencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <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=""/> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</DigestValue> </Reference> </SignedInfo> <SignatureValue>aiYECAxNqK2PivQaRweWajXup5zJa...</SignatureValue> <KeyInfo> <X509Data> <X509Certificate>MIIH1zCCBr+gAwIBA...</X509Certificate> </X509Data> </KeyInfo> </Signature> <bp:pencilOrder> <bp:OrderID>64B4A0D1-814E-4FF6-918A-DD7E7E1AECEA</bp:OrderID> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> </bp:pencilOrder> </bp:signedPencilOrder>
The original pencilOrder element, in blue, is now a child element of the root signedPencilOrders element. More importantly, the signedPencilOrders element now also has another child, the Signature element. This is the element that holds the digital signature information. Included in the Signature element is the algorithm used to canonicalize the data, any transforms performed on the data, the digest algorithm, and the signature algorithm itself. Also included with the signature information is the Reference element, in red, which indicates the data we are interested in validating. In this case, a null URI means that the entire XML document containing the Signature element should be signed. Among other things, the URI attribute could have also included an XPointer reference to indicate a specific portion of this document for which to compute the signature. In our case we are creating a signature for the whole document.
This leads to an interesting problem. If we sign the entire document that envelopes this signature, wouldn't that change when we stick the actual signature value into the SignatureValue node? The DigestValue is also computed as part of the signing process. How can you compute a digest if the data you are computing the digest for will change when you include the digest? The way to avoid such a problem is to use a transform to remove the entire Signature element from the data to be digested and signed. The Transforms element, in green, allows you to perform any transform, but the transform we are using, indicated by the "http://www.w3.org/2000/09/xmldsig#enveloped-signature" algorithm identifier, performs an XPath transform that removes the Signature element. Therefore, changing the DigestValue and SignatureValue elements within the Signature element will not cause recursion problems.
It is good practice to use explicit transforms with the transform code listed in a Transform node. This way you can explicitly include the precise data that you want to sign, instead of relying on exclusion rules to cut out particular nodes. If a message is being passed around to different applications, new nodes could be added that would break an exclusive approach to defining your integrity area. If you use an inclusive approach, you will not run into this problem.
The actual algorithm for creating the digital signature goes something like this: First, grab the data indicated by the Reference element, run it through the specified canonicalization algorithm, send it through any transforms specified, and then compute the digest based on the results. The digest of the reference information is stored in the DigestValue element inside the SignedInfo element. Because tampering with the information (such as our digest algorithm, or our transforms) would invalidate our signing process, the data in the SignedInfo element is now digested and encrypted with the appropriate key to create the final signature, which is placed in the SignedValue element. Notice that the DigestValue of the reference is also within the SignedInfo node, so the SignedValue not only verifies that no one has tampered with our algorithm selections, but it also verifies that the data indicated by our Reference has not been tampered with.
Finally, there is one more optional element within the Signature element that we have not yet mentioned. That is the KeyInfo element indicated in Orange. This is simply a container for holding the key information required to validate the signature. In this case it would hold an X.509 certificate that caries the public key for Alice's Retail Office Supply. Thus, Bob's Pencil Manufacturing Company can easily verify that the order did in fact come from Alice, and that it has not been tampered with along the way.
It is important to note that the initial pencilOrder node, in blue, has one new child element, the OrderID element. A key vulnerability for message protocols that rely on digital signatures is the vulnerability to replay attacks. A malicious person could conceivably empty Alice's bank by resending Alice's signed message over and over again to Bob's Pencil Manufacturing. If Alice includes an identifier, which could take the form of a timestamp, Bob's SOAP message handler could detect whether it had already processed Alice's order or not, and if it had, it would throw out any additional copies it might receive. If SOAP messages are being routed through various paths, it is conceivable that through no malicious action whatsoever, multiple copies of the same order might arrive at Bob's Pencil Manufacturing. Again, the OrderID would allow Bob to realize it had a duplicate, and it could throw out any such requests after the initial order was processed.
XML Encryption
One option for our transaction discussed earlier is that Alice's Retail Office Supply may have wanted to include payment information with the order: Perhaps a credit card number or a purchase order number need to be included, so that Bob's Pencil Manufacturing can get its money. More than likely, Alice's Retail Office Supply does not want the payment information publicly available. Therefore, it makes a lot of sense to encrypt the payment information, so that only Bob's Pencil Manufacturing Company can read it. Let's take a look at what this might look like. We will start by looking at an XML document before encryption or signatures are applied:
<bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> <bank:paymentInfo xmlns:bank="http://www.megabank.com/payspec/1.0"> <bank:PaymentAmount>$999.95</bank:PaymentAmount> <bank:CreditCardNumber>1234123412341234</bank:CreditCardNumber> </bank:paymentInfo> </bp:pencilOrder>
In this case, there is a payment amount and a credit card number included with the order. Alice probably doesn't want her credit card number available to anyone who might see this document, so she will want to encrypt it. Using the W3C's XML Encryption Syntax and Processing working draft as a guideline, an encrypted version of this XML document might look like this:
<bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:OrderID>64B4A0D1-814E-4FF6-918A-DD7E7E1AECEA</bp:OrderID> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> <bank:paymentInfo xmlns:bank="http://www.megabank.com/payspec/1.0"> <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Content"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tipledes-cbc"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:RetrievalMethod URI="#SessKey" Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"/> </ds:KeyInfo> <CipherData> <CipherValue>9oATk2hDK2+HcTVHg...</CipherValue> </CipherData> </EncryptedData> <EncryptedKey Id="SessKey" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:KeyName>Bob's Pencil Manufacturing Company's Public/Private Key</ds:KeyName> </ds:KeyInfo> <CipherData> <CipherValue>CCBPowCwYDVR0PBA...</CipherValue> </CipherData> <ReferenceList> <DataReference URI="#SessKey"/> </ReferenceList> </EncryptedKey> </bank:paymentInfo> </bp:pencilOrder>
The elements from the previous document are highlighted in blue. The difference now is that the credit card number and payment amount has been replaced with an EncryptedData node, highlighted in red. The encrypted data is stored in the CipherValue subelement (it has been truncated here for readability reasons). The data was encrypted with a symmetric triple-DES algorithm. The session key used for encrypting and decrypting the payment data is also included in the document under the EncryptedKey node, in green. The EncryptedKey node has a copy of the session key encrypted with a Public Key for Bob's Pencil Manufacturing. Bob can then use the corresponding private key to decrypt the session key, and once he has the session key, he can decrypt the rest of the payment data.
Using asymmetric encryption algorithms to encode data is computationally expensive, so usually asymmetric methods are only used to encrypt a symmetric key—which is then used to encrypt the majority of the data. Note that there is a KeyInfo element used to describe the Private/Public keys used to encrypt the session key. In this case, it will take the private key to decrypt the information, so it doesn't make sense to send a certificate to Bob's Pencil Manufacturing. Therefore, Bob just has to know how to identify the public key that might have been used. This is why the name associated with the key pair is used.
If we were going to take our order one more step, we would probably now digitally sign the document listed above using the digital signature mechanism we talked about earlier. That way, not only would the parts of the order that should remain private stay that way, but Bob's Pencil Manufacturing would be able to verify that this order did in fact come from Alice's Retail Office Supply.
SOAP Security
Now that we have a feel for how signatures and encryption can work within a generic XML document, how does this differ from what is done with SOAP messages? Further, how can we use the mechanisms provided by the XML signature and encryption specifications to enhance the capabilities of SOAP?
The key to understanding how this can all fit together is to understand what exactly SOAP is. As mentioned earlier in this article, SOAP is simply a message format, but it has some interesting characteristics. First of all, the SOAP message is broken up into two portions: the SOAP header and the SOAP body. The header is used to hold any potential metadata associated with the request, while the body is used to hold the basic data contents that go along with the message.
The fact that we can send metadata with an XML message should actually turn on some light bulbs over the heads of those of you who are more security aware. As far as security is concerned, there is always meta-information that needs to go along with a document. Authentication information is metadata that would accompany a message. Similarly, digital signatures naturally fall into the "meta" field as well. So most of the security data we have looked at so far could easily live in the SOAP headers.
If privacy is a concern, the encrypted data will typically live in the SOAP body. There are certainly cases where some SOAP headers may need to be encrypted, but in most cases, when we speak of privacy issues, we are talking about encrypting part or all of a SOAP body. Even though encrypted XML elements may live in the SOAP body, the corresponding session keys may still be transmitted in the SOAP headers.
At this point, I imagine wheels are spinning in your head about how SOAP signatures and encryption might fall together. So let's take a look at the Web Services Security Language draft and see how it actually defines some of the SOAP security mechanisms. The draft is broken up into three areas: Credential Transfer, Message Integrity, and Message Privacy.
Credential Transfer
The idea of identifying the person who is sending a SOAP message is obviously a key part of any sort of security solution. If you are used to seeing HTTP authentication, the mechanism for passing credentials is a bit different than HTTP's basic authentication. Simply sending a username and password with a request does not usually provide enough security to meet any legitimate need. Usually we talk in terms of sending a certificate, or possibly a Kerberos ticket, as the mechanism for identifying an individual.
The Web Services Security Language draft defines a credentials element that would be passed in the SOAP headers with a SOAP request. The credentials element, like SOAP in general, is very flexible and can hold almost any sort of information. It will often be used to carry X.509 certificates and Kerberos tickets.
Be aware that the credentials header can hold any number of credentials, and they may be used for any number of reasons beyond just authenticating the sender of the message. For instance, you may want to include the certificate that holds the public key used to encrypt a session key. Additional certificates may be included to identify the Certificate Authority chain for a particular certificate. You may want to simply forward a certificate for the sake of including it with the attached message, even if it is not used for performing any encryption whatsoever. But more than likely, you will want to include a certificate for the sake of identifying who sent the message. So here is what this might look like:
<?xml version="1.0" encoding="utf-8"?> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP:Header> <wssec:credentials xmlns:wssec="http://schemas.xmlsoap.org/ws/2001/10/security"> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate>MIIH1zCCBr+gAwIBA...</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </wssec:credentials> </SOAP:Header> <SOAP:Body> <bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:OrderID>64B4A0D1-814E-4FF6-918A-DD7E7E1AECEA</bp:OrderID> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> <bank:paymentInfo xmlns:bank="http://www.megabank.com/payspec/1.0"> <bank:PaymentAmount>$999.95</bank:PaymentAmount> <bank:CreditCardNumber>1234123412341234</bank:CreditCardNumber> </bank:paymentInfo> </bp:pencilOrder> </SOAP:Body> </SOAP:Envelope>
The credentials node, highlighted in blue, holds an X.509 certificate. Notice that we use the KeyInfo element defined by the XML signature syntax that we discussed earlier. The Web Services Security Language draft allows for a lot of flexibility in the format of credential information, but it accepts the XML Signature KeyInfo schema for passing certificates or other key data. It also defines a number of its own mechanisms for passing certificates that are basically equivalent to the KeyInfo approach. Microsoft recommends using the licensing schemas defined in the Web Service License Language draft because they are more flexible and can be strongly typed, providing better schema validation. I use KeyInfo in these examples in order to avoid introducing too many new concepts.
Message Integrity
Simply passing credentials with a message doesn't necessarily achieve a whole lot, since a certificate could be passed with any message from anyone. Because certificates are publicly available, any person could include a certificate with their message, and claim to be that person. Even though HTTP basic authentication is not especially secure, at least it requires knowledge of a user's password, which is better than simply shipping a certificate with a request.
To the credit of the Web Services Licensing Language draft, you can easily include an encrypted username and password in the credentials header, and gain an authentication mechanism significantly better than HTTP basic authentication. We will use XML signature capabilities, however, to extend the ability of sending a public certificate with a SOAP message, so as to achieve an even greater authentication capability than can almost any HTTP authentication scheme. So let's take a look at how this is done in the following example message:
<?xml version="1.0" encoding="utf-8"?> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP:Header> <m:path xmlns:m="http://schemas.xmlsoap.org/rp"> <m:action>http://bobspencils.com/orders</m:action> <m:to>soap://bobspencils.com/orders</m:to> <m:from>mailto:alice@alicesretail.com</m:from> <m:id>uuid:E52F4B79-F37A-47fd-8B2E-F36AFA87D3E6</m:id> </m:path> <wssec:credentials xmlns:wssec="http://schemas.xmlsoap.org/ws/2001/10/security"> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SigningCertificate"> <ds:X509Data> <ds:X509Certificate>MIIH1zCCBr+gAwIBA...</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </wssec:credentials> <wssec:integrity xmlns:wssec="http://schemas.xmlsoap.org/ws/2001/10/security"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI=""/> <ds:Transforms> <ds:Transform Algorithm="http://schemas.xmlsoap.org/2001/10/security #RoutingSignatureTransform"/> <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aiYECAxNqK2PivQaRweWajXup5zJa...</ds:SignatureValue> <ds:KeyInfo> <wssec:licenseLocation> #SigningCertificate </wssec:licenseLocation> </ds:KeyInfo> </ds:Signature> </wssec:integrity> </SOAP:Header> <SOAP:Body> <bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:OrderID>64B4A0D1-814E-4FF6-918A-DD7E7E1AECEA</bp:OrderID> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> <bank:paymentInfo xmlns:bank="http://www.megabank.com/payspec/1.0"> <bank:PaymentAmount>$999.95</bank:PaymentAmount> <bank:CreditCardNumber>1234123412341234</bank:CreditCardNumber> </bank:paymentInfo> </bp:pencilOrder> </SOAP:Body> </SOAP:Envelope>
The credentials node, highlighted in blue, is still in the SOAP headers, as it was in our credential example. There is one key change however. The KeyInfo element now has an ID attribute that indicates that this key can be referenced with the "#SigningCertificate" XPointer. We will see how this is used later.
The big change between this example and the previous example is the new integrity node, shown in red, which has been added to the SOAP headers. The integrity node contains our old friend the signature node from the XML signature syntax. For the most part, this is exactly like the signature syntax that we looked at before. There are a couple differences, however.
First of all, notice that the algorithm for the CanonicalizationMethod element is not the same as what we looked at before. The reason is that there becomes some namespace ambiguity when you start enveloping XML documents in other XML documents. In order to avoid ambiguity so that signatures work out correctly, it is important that we use exclusive XML canonicalization, which is defined by the W3C Exclusive XML Canonicalization draft. SOAP messages could potentially fall into this trap quite frequently, since XML documents will often be wrapped in other XML documents during the processing of SOAP messages.
Also, notice that we have a different transform listed for our signature than we had in the XML signature example. This is because SOAP messages are designed to be able to be routed from one location to another. In order to verify the route that our message intends, the RoutingSignatureTransform signs not only the body of the request, but also the routing information located in the path node (shown in green), located in the SOAP headers. The second transform listed above helps to address the exclusive XML canonicalization issue. Finally, the last difference is simply that the KeyInfo node now refers back to the credentials node that contains the key we assigned the "SigningCertificate" ID. This way, the certificate information is all in one place in the SOAP message, and has the added distinction of being considered a license.
The result of our example is that now the integrity of the SOAP message is guaranteed. Not only will Bob's Pencil Manufacturing know that this SOAP message came from Alice's Retail Office Supply, but it can verify that the message has not been altered, since Alice's Retail Office Supply signed it. We have message authentication and integrity, without knowledge of the underlying transport.
Message Privacy
Finally, we need to get back to the fact that Alice doesn't want her credit card information to be visible to anyone who might see her SOAP order message. The need for privacy is obviously a critical component of many security requirements. The beauty of XML encryption is that it allows for encrypting only what needs to be encrypted. Extra processing cycles are not burnt by encrypting every byte sent between two applications. More importantly, particularly in the vision of SOAP messaging for the future, all or part of a SOAP message may need to be processed by multiple nodes.
For instance, in the case of an order like Alice is sending, part of the message may need to go to the shipping department for fulfilling the order, part may need to go to accounts payable for the financial transaction, and the whole message may need to be forwarded to an auditing system for historical storage. The shipping department needs to know the details of the actual pencils ordered, but does not need to know the payment details. They may still, however, need to verify that the message came from Alice's Retail Office Supply.
If we were encrypting the entire message, then the entire message would have to be decrypted in order for anyone to process it. This would expose Alice's financial information to people who do not need to know it. And if you consider the previous methods of providing privacy by using SSL encryption to only encrypt the underlying transport channel, then every point through which the message was routed would be able to see all of the payment details.
The power of XML encryption even makes it conceivable that Alice could encrypt her payment information, plus a few additional details, with a banking institution's public key. Bob's Pencil Manufacturing Company would simply forward the encrypted payment info to the banking institution where it would be decrypted, and funds would be transferred to Bob's Pencil Manufacturing according Alice's encrypted directions. Bob would simply get verification that the funds transfer took place from the bank, and he would ship the order without knowing any of Alice's account details.
The additional details in the encrypted message would have to include information indicating that the funds need to be transferred to Bob's Pencil Manufacturing (so others couldn't forward the same encrypted data to the bank and expect to receive payment), and a transfer ID of some sort, so that if the bank received the same message multiple times from Bob's Pencil Manufacturing, it would realize it had already transferred the funds for that transfer ID, and would not debit Alice's account multiple times.
So let's take a look at what a SOAP message that uses encryption might look like.
<?xml version="1.0" encoding="utf-8"?> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP:Header> <wssec:credentials xmlns:wssec="http://schemas.xmlsoap.org/ws/2001/10/security"> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SigningCertificate"> <ds:X509Data> <ds:X509Certificate>MIIH1zCCBr+gAwIBA...</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </wssec:credentials> <wssec:integrity xmlns:wssec="http://schemas.xmlsoap.org/ws/2001/10/security"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI=""/> <ds:Transforms> <ds:Transform Algorithm="http://schemas.xmlsoap.org/2001/10/security #RoutingSignatureTransform"/> <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aiYECAxNqK2PivQaRweWajXup5zJa...</ds:SignatureValue> <ds:KeyInfo> <wssec:licenseLocation> #SigningCertificate </wssec:licenseLocation> </ds:KeyInfo> </ds:Signature> </wssec:integrity> </SOAP:Header> <SOAP:Body> <bp:pencilOrder xmlns:bp="http://bobspencils.com/pencilOrders"> <bp:OrderID>64B4A0D1-814E-4FF6-918A-DD7E7E1AECEA</bp:OrderID> <bp:pencilType>bp:StandardNumberTwo</bp:pencilType> <bp:quantity>100,000</bp:quantity> <bank:paymentInfo xmlns:bank="http://www.megabank.com/payspec/1.0"> <enc:EncryptedData xmlns:enc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Content"> <enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tipledes-cbc"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:RetrievalMethod URI="#SessKey" Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"/> </ds:KeyInfo> <enc:CipherData> <enc:CipherValue>9oATk2hDK2+HcTVHg...</enc:CipherValue> </enc:CipherData> </enc:EncryptedData> <enc:EncryptedKey Id="SessKey" xmlns="http://www.w3.org/2001/04/xmlenc#"> <enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:KeyName>Bob's Pencil Manufacturing Company's Public/Private Key</ds:KeyName> </ds:KeyInfo> <enc:CipherData> <enc:CipherValue>CCBPowCwYDVR0PBA...</enc:CipherValue> </enc:CipherData> <enc:ReferenceList> <enc:DataReference URI="#SessKey"/> </enc:ReferenceList> </enc:EncryptedKey> </bank:paymentInfo> </bp:pencilOrder> </SOAP:Body> </SOAP:Envelope>
The message above is really a trivial combination of the SOAP signing example we just looked at, along with the XML encryption sample we looked at earlier. The EncryptedData element and the EncryptedKey element, highlighted in blue, are basically in the same format as our XML encryption example. Often, session keys will be passed in a license within the credentials header. You would then use the wssec:licenseLocation tag to refer to the certificate in the credentials header, just like we do in the ds:Signature node. Other than that, you are basically talking about normal XML encryption.
Conclusion
With the groundbreaking work done in the XML signature and encryption standards, SOAP is now able to take the next step of providing world-class security for SOAP messaging. This is not to say that protocol-level security is a thing of the past, and there are many instances where protocol-level security may make more sense, even when tools come to fruition that would make using SOAP-level security easy to implement. Yet the world-class security, and the flexibility provided by the SOAP security mechanisms, will enable applications to be created, the likes of which have only been envisioned in the past.
No comments:
Post a Comment