Supporting Digital Signatures Within SOAP Messages

Supporting Digital Signatures Within SOAP Messages

eb services is the latest wave in distributed computing. Its ability to connect clients and servers independent of platform, programming language, and transport protocol gives it great promise. The potential for businesses to conduct highly confidential and proprietary transactions, all the while being assured of the integrity and authenticity of their data. There would be a guarantee that the person sending the document is who they say they are and that the data has not been tampered with. Historically, digital signatures address these security concerns.

SOAP (Simple Object Access Protocol), one of the many specifications contributing to the success of Web services, is being positioned to replace EDI as the de-facto commercial B2B exchange. SOAP defines the XML document structure for sending Web service requests and responses. It is possible to send SOAP messages over the HTTPS protocol, providing encryption of the data. However, there are other security requirements to address if SOAP is to be completely embraced for B2B transactions.

There is an existing specification outside the Web service realm, called XML-Signature, that describes how to represent a document and its corresponding signature in XML format. Now there is a W3C Note, SOAP-DSIG that defines how to digitally sign SOAP messages. How do all these pieces fit together? Piecing these elements together using Java, this article provides step-by-step, how-to instructions for you to build a complete solution that enables secure Web services.

Listing 1 shows the same SOAP document both with and without an XML signature for comparison.

What You Will Need on the Client-Side
A client application wishing to invoke SOAP requests that contain digital signatures requires several toolkits. This section details the required toolkits and how they interoperate. Although it is possible to write directly to the SOAP protocol from a Java application, it is much simpler and quicker to use a toolkit that hides the low-level details. This article assumes you are using such a toolkit. At this time there are no SOAP toolkits for mobile or embedded devices; only standard desktop platforms are supported.

SOAP Toolkit
A SOAP toolkit provides the following set of features (at a minimum):

  • a WSDL to Java Generator (generates Java stubs for accessing a service defined in WSDL)
  • a SOAP RPC API (provides an abstraction of underlying SOAP protocol)
  • a UDDI Registry Browser

Click here for a list of available, free toolkits.

Cryptographic Toolkit
A toolkit is required to generate keys and digitally sign documents, and there are plenty of cryptographic providers available (unless you want to provide your own implementation). The minimal security components are listed below:

  • Support for a digital signature algorithm. Available algorithms are: DSA (Digital Signature Algorithm) or RSA (Rivest, Shamir, Adelman) or ECC (Elliptical Curve Cryptography). ECC is the latest algorithm licensed by Certicom, Inc. for which there is little support from other vendors.
  • Support for a message digest/hash algorithm. Sampling of available algorithms are: MD2, MD5, SHA-0, SHA-1.

Although it’s not required, API support for XML Signatures is a feature well worth having?it can save you valuable time and effort. Having said that, there is no standard API for achieving this, so use of such a toolkit does introduce a 3rd party dependency into your solution. Two such toolkits exist.

The JCE (Java Cryptography Extension) specification by Sun provides a reference implementation that contains support at a minimum for RSA and MD5. It has been integrated into Java 2 SDK version 1.4. For Java 2 SDK versions 1.2.x and 1.3.x, the JCE 1.2 (JCE 1.2.1 for export) is an optional package that you need to download and install separately. It allows for 3rd party vendors to provide implementations that plug in to the architecture. These vendor implementations will often provide support for a larger selection of algorithms. Here is a list of companies that provide open source JCE implementations.

XML Parser
In order to generate the final XML-Signature, you’ll need an XML parser capable of generating XML documents. You’ll also need an XML parser to generate the final SOAP document. There are a number of publicly available ones that will suffice. The best one is Apache Xerces Parser. Combine this with the Sun JAXP API to provide an API that is independent of the underlying XML processor implementation.

The XML Signature is specified as a SOAP Header attribute. You insert the XML Signature document through the SOAP toolkit. There is an example of how this is done later in this article.

What You Will Need on the Server-Side
The amount of software required for the server is greater than that required for the client. In addition to an XML parser and a cryptographic toolkit, you will need a SOAP Engine, a Webserver/Servlet engine, and a PKI vendor.

SOAP Engine
The server requires a SOAP toolkit and also a SOAP engine capable of processing SOAP requests containing the embedded digital signatures. Currently, only one such engine exists, the WASP Advanced Server by Systinet. All SOAP engines should provide the following set of features:

  • Java to WSDL Generator (generate WSDL from Java services to be published)
  • Java to UDDI Generator (generate UDDI from Java services to be published)
  • Publish Java services to a public UDDI registry.

Web Server/Servlet Engine
A Web server and servlet engine architecture are required to process requests. Any J2EE application server meets this requirement, though a minimal configuration requires only a Web server and a servlet engine. Click here for list of the leading application servers.

As Web services are embraced, application servers are likely to provide the more SOAP-related features currently offered by Web services vendors, potentially including the actual SOAP engine, which would also need to include support for digital signatures.

PKI Vendors
Digital Signature technology is a small piece of a much larger picture; the Public Key Infrastructure (PKI). PKI provides an objective 3rd party that ensures the non-repudiation and integrity of the data required for the digital signature(s) to be legally binding. Signers register themselves, and subsequently their credentials (private/public key pair), with a Registration Authority (RA). Assuming the RA authenticates the user successfully, the Certificate Authority (CA) issues a digital certificate that represents the signer’s public key, contains an expiration date, and is signed with the CA’s own private key to prove that it was the CA and not an imposter.

On the server, where verification is done in a typical PKI, a connection to the CA/RA (jointly called the PKI) is required. Usually, the certificates are stored in LDAP directory structures and are in the X.509 format. Depending upon the security and maintenance needs of your business, you can choose to host the CA, RA, and LDAP directories locally or remotely at a site controlled and secured by the PKI vendor. There are a number of PKI vendors from which to choose. Depending on other requirements, it may make sense to choose the same vendor for the cryptographic libraries as for the PKI implementation. Click here for a list of PKI vendors.

There are a few important features to consider when evaluating PKI vendors:

  • Adherence to PKCS (Public Key Cryptographic Standards). This is a set of standards created and maintained by RSA Security to promote interoperability in the PKI industry.
  • Cryptographic toolkits?do they provide Java toolkits that adhere to the JCE specification?
  • Cryptographic toolkits?do they provide an implementation for the XML-Signature specification? This could be a valuable development time-saver.

Putting It All Together
Now that you’ve got all the required components, it’s time to find out how the client submits a SOAP Request containing a Digital Signature to the server and receives the response. Figure 1 is a diagram of both client and server side processing that will serve as a reference for the remainder of this article.

Figure 1 is diagram of both client and server side processing.

Looking at the client processing, it is assumed that you’re using the Apache Axis and Apache XML Security projects. If you’re using a different toolkit(s), the code samples will have to be modified accordingly, but the underlying functionality will remain the same.

Client Signature Processing
Generate a private and public key pair and optionally a certificate. The cryptographic toolkit provides APIs for doing both. To generate the certificate, the client needs to specify their Distinguished Name (DN). This helps to uniquely identify their certificate in the certificate repository. Digital Certificates can be in a number of formats, the most common of which is the X.509 format, upon which LDAP is based. For this reason, most PKI vendors store their certificates in a LDAP repository. For further details of directory structure attributes, refer to LDAP or X.509 documentation.

Once the keys are generated (on the client device for maximum security), submit the public key and optionally the certificate to a 3rd party CA. The CA can either be a publicly available repository or a dedicated CA repository. Either way, there is a fee for each certificate issued and the Registration Authority (RA) must authenticate the user submitting the certificate.

Often, the PKI vendor provides proprietary authentication mechanisms as well as facilities for generating the key pairs and certificate on behalf of the user. In such a case, the PKI vendor needs to provide secure mechanisms for transporting the private key to the client. The approach you choose will depend on your individual application’s needs. However, the submission of a certificate to a CA is highly proprietary and not provided for by the toolkits.

Author’s Note: There is an emerging standard developed by Verisign, Microsoft, and WebMethods to address this issue?the XML Key Management Specification (XKMS). Click here for more information about this nascent standard.

Once the keys and certificate have been generated and published, the client is ready to sign documents. First, the client must identify what document needs signing. This is one of the missing pieces in the entire SOAP-Digital Signature puzzle. Traditionally, with XML Digital Signatures, the client provides the data to be signed which is input to a hash algorithm, but the entire XML Signature document is signed, not just the original data. But what is signed for a SOAP message that contains an embedded XML Signature?

Following the XML-Signature paradigm, the SOAP body element is signed, which allows for the recipient to verify that the client message/request was not tampered with in transit. This means that the SOAP processing must occur first. Client SOAP Processing
The client identifies the Web service interface description to which it is submitting a request. This can be done either through a UDDI browser, which is part of the SOAP client-side toolkit or through verbal/written communication with the service provider, if it is an internal enterprise application. Once the service endpoint is identified, the client generates the stub files through the use of the SOAP toolkit generator. The client writes the code to invoke the SOAP request, providing the necessary data, such as service endpoint URL and method argument values. The following code shows how to do this:

Service service = new Service();Call call = (Call) service.createCall();call.setTargetEndpointAddress(new"http://localhost:8080/axis/servlet/AxisServlet));	SOAPEnvelope env = new SOAPEnvelope();// XMLUtils.StringToElement() creates an XML Element for the given // (namespace, elementName, textValue) combinationSOAPBodyElement sbe = new SOAPBodyElement(XMLUtils.StringToElement("http://localhost:8080/MyService", "methodName", ""));env.addBodyElement(sbe);	// Invoke service	call.invoke(env);	// Get responseMessageContext mc = call.getMessageContext();Message response = mc.getResponseMessage();

Next, add the logic to sign the SOAP body element. The key gains access to the SOAP body element. Once the body element has been extracted from the SOAP document, it becomes the input for the XML-Signature document processing. The following code sample does this using Apache Axis and XML Security packages.

// SOAPEnvelope has already been created and is stored in env// Actually add the SOAP signature headerenv.addMapping(new Mapping("", "SOAP-SEC"));env.addAttribute(Constants.URI_SOAP_ENV, "actor", "some-uri");env.addAttribute(Constants.URI_SOAP_ENV, "mustUnderstand", "1");SOAPHeader header = new SOAPHeader(XMLUtils.StringToElement(SOAPSECNS, "Signature", ""));env.addHeader(header);// Get the SOAPEnvelope as a XML Document so we can extract the SOAP// Signature element just added for use in creating the XML Signature.StringWriter writer = new StringWriter();SerializationContext serializeContext = new SerializationContextImpl(writer, null);env.output(serializeContext);writer.close();Reader reader = new StringReader(writer.getBuffer().toString());Document doc = XMLUtils.newDocument(new InputSource(reader));// Get the Signature Element from the HeaderElement soapHeaderElement = (Element) ((Element) doc.getFirstChild()).getElementsByTagNameNS("*", "Header").item(0);Element soapSignatureElement = (Element)soapHeaderElement.getElementsByTagNameNS("*", "Signature").item(0);	// http://xml-security is the base-uri, which needs 	??to be unique within documentXMLSignature sig = new XMLSignature(doc, "http://xml-security",XMLSignature.ALGO_ID_SIGNATURE_DSA);// Add SOAP Body to XML Signature and sign.soapSignatureElement.appendChild(sig.getElement());// Neat trick: since the XMLSignature is actually a part of the// SOAP XML document, the SOAP body is referenced as a URI fragmentsig.addDocument("#Body");

Most of the commercial cryptographic toolkits provide APIs for generating an XML-Signature document, given the data to sign, the private key, and the public key/certificate. The following code shows how to do this (again, assuming Apache Axis and Apache XML Security toolkits). For simplicity, the code retrieves the private key from a key store. This is not recommended for deployment scenarios with high security needs since the key store provides minimal protection for the private key.

// Extract the private key & certificate from the key store KeyStore ks = KeyStore.getInstance("JKS");FileInputStream fis = new FileInputStream("keyStoreFileName");            ks.load(fis, "keyStorePassword".toCharArray());       	PrivateKey privateKey = (PrivateKey) ks.getKey		("privateKeyAlias",		                    "privateKeyPass".toCharArray());X509Certificate cert =                    (X509Certificate) ks.getCertificate					("certificateAlias");	// Add the digital certificate and public key to XML //Signature document. Assumption is XMLSignature document //was created earlier. See above code sample       sig.addKeyInfo(cert);       sig.addKeyInfo(cert.getPublicKey());	// Sign the XML Signature document with our private key       sig.sign(privateKey);	// Transform XML Signature Document       Canonicalizer c14n =        		Canonicalizer.getInstance			(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);	// Assumption is Document was extracted from SOAP Envelope earlierbyte[] canonicalMessage = c14n.canonicalizeDocument(doc);	// Create a Deserializer for the XML Signature documentInputSource is = new InputSource(new; AxisClient tmpEngine = new AxisClient(new NullProvider());// env is SOAPEnvelope instanceDeserializationContextImpl dser = new DeserializationContextImpl(is, new MessageContext(tmpEngine), Message.REQUEST, env);dser.parse();

Now the SOAP document, a single XML document, is ready for transport to the server. Server Signature Processing
Once the server receives the SOAP document, verify that the document is from the correct user and that it has not been altered in transit. Most SOAP engines are J2EE servlets and process all requests that arrive for a particular URL. If the SOAP Engine provides support for embedded XML-Signature documents, your work is pretty simple.

Currently, there is one SOAP engine that provides automatic digital signature support, WASP Advanced Server by Systinet. For all other cases, you’ll need to intercept the SOAP document, extract the header element, and verify the signature prior to processing the SOAP request. To do this, use the SOAP toolkit, the cryptographic toolkit, and the PKI vendor. The verification steps are outlined below:

  • Extract the header element from the SOAP message using the SOAP engine/toolkit.
  • Get the contents of the SOAP body element (the original data that was signed) for use in verification.
  • Parse the XML-Signature document to extract the public key, algorithm details, and signed data using the XML Parser (and possibly the cryptographic toolkit, if yours provides an API for handling XML-Signature documents).
  • Verify the signature by creating the digest from the SOAP body element with the public key.
  • (Optional) Retrieve the certificate from the certificate repository managed by the PKI.
  • (Optional) Verify that the certificate is not on a Certificate Revocation List (CRL). This ensures that the associated key pair has not expired and the security of the private key has not been compromised.

Next, add the logic to sign the SOAP body element. The key gains access to the SOAP body element. Once the body element has been extracted from the SOAP document, it becomes the input for the XML-Signature document processing. The following code sample does this using Apache Axis and XML Security packages.

Server Configuration
These instructions are for configuring Tomcat 4.04 Beta2 for use with the Apache Axis SOAP engine and the Apache XML Security package to enable the code samples to work. However, it is safe to assume that similar configuration is required for other SOAP engines and J2EE application servers.

  1. Download the Axis distribution. This has several dependencies, which are:
  • Download a JAXP 1.1 compatible XML parser. Try Xerces2 Java Parser from Apache or the JAXP from Sun.
  • Download the Apache-XML-Security-J 1.0.2 toolkit (this provides implementation for the “XML-Signature Syntax and Processing” recommendation, which is essentially the ability to create XML Digital Signature documents as well as encryption algorithms).
  • Download a JCE provider implementation. Click here for a list of open-source JCE implementations.
  • Configure Tomcat (Version 4.04) by adding the following jars to the webapps/axis/web-inf/lib directory:
    • xmlsec.jar (XMLSecurity class files)
    • JCE jar file (if you are using the Bouncy Castle JCE provider, it requires you to actually create the JAR since the distribution comes with a directory of class files).
    • Logger jar file (bundled with XMLSecurity project) Replace the log4j-core.jar that is part of Axis with the jakarta-log4j-1.2beta2.jar from XMLSecurity.
    • XML Parser jar files (bundled with XMLSecurity project)
    • xmlParserAPIs.jar
    • xercesImpl.jar
    • xalan.jar (bundled with XMLSecurity project)
    • xml-apis.jar (bundled with XMLSecurity project)
  • Add these jar files to your client classpath environment variable as well.
  • Code Sample
    The following code shows the processing that takes place within the invoke() method of an Apache Axis handler. This handler is the first in the chain of handlers. Assuming the signature verification succeeds, the next handler in the chain (aka the user service handler) is invoked. On failure, the target service is not invoked. The chain of handlers to invoke is specified as part of the SOAP engine configuration. In the case of Axis, it is part of the WSDD (Web Services Deployment Descriptor).

    Message inMsg = msgContext.getRequestMessage();       Message outMsg = msgContext.getResponseMessage();       // Verify signed message       Document doc = inMsg.getSOAPPart	   ().getAsSOAPEnvelope().getAsDocument();       String baseURI = "http://xml-security"; 	   // must match baseURI in client code       CachedXPathAPI xpathAPI = new CachedXPathAPI();Element nsctx = doc.createElement("nsctx");nsctx.setAttribute("xmlns:ds", Constants.SignatureSpecNS);Element signatureElem = (Element) xpathAPI.selectSingleNode(doc,       		"//ds:Signature", nsctx);// Check to make sure that the document claims to have been signed       if (signatureElem == null) {   		// handle and log errorreturn;}       XMLSignature sig = new XMLSignature	   (signatureElem, baseURI);       boolean verify = sig.checkSignatureValue	   (sig.getKeyInfo().getPublicKey());	if (verify == false){		// signature verification failed - 		//do not forward request to SOAP Service.}

    Server SOAP Processing
    As mentioned earlier, the SOAP Engine handles all requests that adhere to a specific URL. All of the existing SOAP engines on the market today either come as part of a pre-bundled J2EE application server and/or interoperate with leading application servers. The SOAP Engine parses the SOAP document, extracting the target service, which it maps to the appropriate Java class and method based on configuration. The Java method is invoked.

    In most cases, if the SOAP Engine does not process the Signature header element, the Java class providing the Web Service will need to do so (or delegate the task to another component). This requires the service provider to know that the request came in as a SOAP request, which makes things more complicated. Alternatively, if you write a general SOAP handler, it should intercept all signed SOAP requests and extract the Signature header element and SOAP body element for signature verification purposes.

    Once verification succeeds, the SOAP engine forwards (using SOAP Engine forwarding if available or a proprietary forwarding mechanism) the request to the target endpoint for processing. For example, in the code sample above, the SOAP Engine (Apache Axis) forwards the request to the next handler in the chain based on deployment descriptor information. If the SOAP engine has an interceptor for signature processing, make sure that this interceptor does the work rather than your handler.

    When the appropriate method has been invoked and performs the requested action, it returns, unaware a SOAP client has invoked it. The SOAP Engine is responsible for bundling and encoding the response for submission to the client. The assumption here is that the response is not digitally signed.

    Want To Ride the Wave?
    The ability to digitally sign a SOAP document is definitely achievable and straightforward and leveraging the existing set of SOAP and Digital Signature toolkits, both open source and commercial, can save time and effort.

    The emerging industry standards for SOAP, digital signatures, and their intersection can be an enormous asset to businesses, enabling developers to build standards-compliant applications that are interoperable with other toolkits. However, the pieces of the puzzle don’t fit quite yet: the actual integration point between SOAP processing and digital signature processing, especially on the server-side, needs some work.

    Should this functionality be provided by a SOAP or Digital Signature toolkit? There is currently one SOAP engine (WASP by Systinet) that does so. In the future, perhaps other SOAP engines and/or digital signature toolkits will also offer this feature. With a rapidly changing industry landscape, it is important to track the development and acceptance of the SOAP specification?especially the SOAP-DSIG note?as well as the emerging XKMS standard to ensure that your applications are interoperable and ready to ride the wave.


    About Our Editorial Process

    At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

    See our full editorial policy.

    About Our Journalist