Welcome!

Industrial IoT Authors: Elizabeth White, Stackify Blog, Yeshim Deniz, SmartBear Blog, Liz McMillan

Related Topics: Industrial IoT

Industrial IoT: Article

Securing and Authenticating SOAP-Based Web Services

Securing and Authenticating SOAP-Based Web Services

If you are implementing a multiuser system, your system will probably have certain attributes. It may be implemented in a distributed fashion and it may have some sort of security model. In its most basic form, such a system can be represented by a straight line on a piece of paper: below the line is the information, content, data (call it what you will); and above the line are the various individuals, groups, and roles that need to work with what is below the line.

We connect clients above the line to the data below it by exposing services that provide access through the line. These services describe the operations that may be performed upon the data. The security model implemented within the service layer determines who may perform those operations and upon which particular bits of data. To the extent that these services are the only way to access the data, our line is now a secure perimeter.

To complete the picture, the services need to be able to identify the clients. Using SOAP to implement these services gives us a number of options, each with its advantages and disadvantages, and each in various stages of development. Basic Authentication and SSL

Apache SOAP 2.1 introduced basic authentication and HTTPS support. The SOAPHTTPConnection object includes two methods, setUserName() and setPassword(), and its send() method uses them to construct an "Authorization" header for the HTTP POST. With this header, the SOAP client will be authenticated against the HTTP daemon receiving the request and, assuming success, the request will be passed off to the SOAP endpoint. Of course, without HTTPS support, the credentials - though base-64 encoded - would be sent in the clear, so be sure to use SSL when using this technique.

Basic authentication is pretty much just that. The weaknesses are well known and, for the most part, come down to the ease with which passwords are compromised, which can be as simple as someone looking over someone else's shoulder.

SOAP Digital Signature
The IBM alphaWorks Web Services Toolkit (WSTK) version 2.3, and Apache AXIS (not yet in first, full release as of this writing) include support for SOAP Digital Signature. (More information can be found at www.w3.org/TR/SOAP-dsig/.) In short, it enables you to digitally sign the body of a SOAP envelope and include the signature information in the envelope header. In order to understand exactly what this does for you, you need to understand, at the highest possible level, what public key cryptography (PKC) does for you.

PKC uses a two-part key system: one part is kept secret and known only to the key owner, and the other part is public and known to everyone. The relationship between the keys is such that it isn't possible (for all practical purposes) to derive one key from the other. Using your public key, people can create encrypted messages that only you can decode.

The second benefit is digital signature. Using your private key, you can sign a block of data - in the case of SOAP digital signatures, the SOAP envelope body. While signing a message does not encrypt it, it does guarantee its integrity. Using your public key, anyone with the signature and an intact copy of the signed message can verify that you signed that message. If either the message or the signature is altered, signature verification will fail. Digital signatures can be used for authentication if the authenticator challenges a client who then signs the challenge and returns it. If the challenge is unique each time (a nonce), the authentication process can't be replayed.

PKC wonks will cringe at the brevity of this explanation, but since numerous books have been written on the topic, we can only recommend that interested readers seek one out. On the other hand, this is sufficient information to determine that SOAP digital signatures, while useful, are not, nor are they intended to be, an authentication mechanism as such. Quoting from the W3C note mentioned earlier:

For example, digital signatures alone do not provide message authentication. One can record a signed message and resend it (replay attack). To prevent this type of attack, digital signatures must be combined with an appropriate means to ensure the uniqueness of the message, such as nonces or time stamps. One way to add this information is to place an extra <http://www.w3.org/2000/09/xmldsig#Object> element that is a child of <http://www.w3.org/2000/09/xmldsig#Signature>.

So, to use SOAP digital signatures as an authenticating mechanism, you must do a bit of work, but it can be done. It's a bit harder than it sounds, since time stamps tend to introduce timing windows, and a nonce-based scheme would make the service request more conversational than you would like. Without modification, SOAP digital signatures will tell you who signed the message, but not who is delivering the message. There is, however, another authentication mechanism based on certificates at our disposal that we have yet to consider.

SSL with Digital Certificate Authentication
Step 1: An SSL Example
We've already taken a brief look at the authentication support in Apache SOAP 2.1, including the SSL support. If you look at SSLUtils.java, you will find this bit of canonical code:

SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(host, port);
sslSocket.startHandshake(); return sslSocket;
It's the SSL handshake part that's interesting: it allows the server and client to authenticate each other (typically using PKC), and to negotiate an encryption algorithm and cryptographic keys before the application protocol transmits or receives its first byte of data. Things can go wrong, such as the client and server not having any cipher suites in common, or either the client or server not being able to encrypt at the strength required by the other.

Peer authentication may also be made part of the process - most of us have run into a secure site, the name of which does not agree with its certificate, resulting in a warning from the browser that the site should not be trusted. Both sides of the connection may be subject to peer authentication, and it's this stage that gives us our opening: during this stage, credentials in the form of digital certificates are exchanged.

What is a certificate? As everybody can generate a key pair, there needs to be a process by which a key pair is tied to an identity. This gives rise to the concept of the Certification Authority (CA), which is an external service that verifies your identity and digitally signs your public key. A certificate, in its most basic form, then consists of your key pair, some information about you, such as your name, along with the digital signature of a CA.

For this to work it's critically important that both parties in the authentication process "trust" the CA that signed the certificates that are being exchanged. You trust a CA by putting a copy of the certificate of the CA - minus its private key - into a designated location called the truststore. The decision as to whether a particular certificate passed along during the SSL handshake process should be trusted or not is then made by comparing the certificate of the CA that signed it with the list of trusted CA certificates in the truststore.

Let's start with a simple service request over SSL and see what happens. To do this, you will need a copy of Apache SOAP (we used 2.1) and the Java Secure Socket Extension. (We used version 1.0.2, http://java.sun.com/products/jsse/. It has since been included in JDK 1.4, but it hadn't been fully released at the time of this writing.) Finally, your HTTP server/servlet container combination must support SSL, and later we will require SSL with client authentication through certificates.

Most servers support certificate-based authentication. Apache supports it via a third-party product, Covalent SSL. IIS natively supports static certificate mapping to NT accounts, while in a Windows 2000 environment certificates are managed via Active Directory.

We used Allaire JRun 3 under IIS 5. Enabling the use of SSL with JRun applications under IIS isn't obvious, but it is documented in the Allaire/Macromedia knowledge base. In short, you have to secure the JRun DLL. Looking at the management console for IIS, you will find the JRun DLL in the scripts directory. Right-click over the DLL, select Properties, click on the File Security tab, and find the Secure Communications area (see Figure 1). Once you have installed a certificate on the Web server, clicking on the Edit button will enable you to turn on SSL. Later, we will use the same dialog to turn on client certificate authentication.

If, like us, you have generated your own server certificate using the Windows 2000 Certificate Server, you'll need to tell the client that it can trust the CA that issued that certificate. In our case, that authority was the Windows 2000 Certificate Server, and we simply export a base-64 encoded version of the authority's certificate and add it to the JDK's "cacerts" keystore - the truststore and the default repository for trusted CAs. Assuming the exported certificate was named "server.cer", the following JDK keytool command would add the key to the truststore with the alias "TestCA":

\jdk\bin\keytool -import -file server.cer -keystore \jdk\lib\security\cacerts -storepass changeit -alias TestCA
Answering "yes" to the query to trust the certificate will cause the JDK to "trust" your server.

Now let's see if everything is installed correctly. Compiling the code in Listings 1 and 2, deploying the service, and running the client should yield predictable results. Once you have placed the TestService class file in the SOAP WEB-INF\classes directory (or somewhere else the servlet will find it), you may deploy the service with the following command:

\jdk\bin\java -Djava.protocol.handler.pkgs= com.sun.net.ssl.internal.www.protocol org.apache.soap.server.ServiceManagerClient https://localhost/soap/servlet/rpcrouter deploy TestService.xml
TestService.xml should contain the following:
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:TestService">
<isd:provider type="java" scope="Session" methods="testMethod">
<isd:java class="TestService" static="false"/>
</isd:provider>
<isd:faultListener>
org.apache.soap.server.DOMFaultListener </isd:faultListener>
</isd:service>
The command to run it should look something like this:
\jdk\bin\java -Djava.protocol.handler.pkgs= com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=all TestMain string
Including the debug option causes the various stages of the SSL handshake to be printed out nicely.

If you then alter the security on the JRun DLL to require client certificates and run the example again, you should receive an exception and will possibly see the page sent by IIS rejecting the attempt to connect.

If you would like to know more about the nuts and bolts of SSL, the JSSE Guide has an excellent description of how SSL works and what happens during the handshake.

Step 2: Generating a Key
Next create a keystore and a key with which you can experiment. First, generate a key for your client to use in authentication. Something like the following should do the trick and generate a new keystore named "TestClientStore" with a key pair called "TestClientCert":

\jdk\bin\keytool -genkey -keyalg rsa -keystore
TestClientStore -storepass TestStorePass -alias
TestClientCert -keypass TestKeyPass
You will be asked to provide information that identifies you. At this point, TestClientCert is a "self-signed" certificate; in other words, nobody other than you has verified who you claim to be. Thus, to generate a request for your CA to validate your identity and to sign your key (called a PKCS#10 request), type:
\jdk\bin\keytool -certreq -alias TestClientCert -file CertRequest.p10 -keypass TestKeyPass -keystore TestClientStore -storepass TestStorePass
When visiting the Windows 2000 Certificate Authority Web page to request a certificate, you will want to make an "advanced" request for a client certificate, then, "Submit a certificate request using a base-64 encoded PKCS #10 file or a renewal request using a base-64 encoded PKCS #7 file." Submit the file, "CertRequest.p10", download the "CA certification path" to a file called "client.p7b" and run the following to replace your self-signed certificate with the certificate signed by your trusted CA:
\jdk\bin\keytool -import -file client.p7b -keystore TestClientStore -storepass TestStorePass -alias TestClientCert -keypass TestKeyPass
The keystore now contains a key that can be used by your client to authenticate itself. To avoid the complications of Active Directory, you can use static client-certificate mapping on the Web server. To do this, you must export a copy of your public key to a file with the following:
\jdk\bin\keytool -export -keystore TestClientStore -storepass TestStorePass -alias TestClientCert -file client.cer -rfc
The final step in this public key odyssey is to map the key you just exported to a user account. Revisit the secure communications setup for the JRun DLL, enable client-certificate mapping, and then edit the account mappings. Add a mapping, then choose the client certificate you just exported and map it to an account to which you know the password. If you followed the example, the server will trust the client certificate without you telling it to do so explicitly, as the CA that signed it was the same CA that signed the server certificate earlier on.

That was a great deal of cookbook work, so here is a brief account, in more abstract terms, of what you just did:

  • Added your certificate authority's public key to cacerts keystore of trusted CAs in order to "trust" your CA
  • Created a new keystore; keystores are used by Java to hold public and private keys for encryption/decryption and digital signature operations
  • Generated a personal public/private key pair
  • Generated a request for that key to be signed by your CA
  • Had your CA sign that key so the user of the key would be trusted by anyone who trusts the CA
  • Imported the CA response into the keystore
  • Exported the signed public key
  • Mapped the public key to an NT account in IIS

    A similar series of steps would be followed for authenticating any combination of Web servers, servlet containers, and self-run or commercial certificate authorities.

    Note that you may be able to simplify things a little bit in certain situations:

  • If you are using the services of a commercial CA, the first step may not be necessary, as the cacerts keystore is installed with a set of vendor certificates that are trusted by default. Also note that nothing prevents you from bypassing the cacerts keystore altogether and storing all your public and private keys in one keystore. (See the comment in the TrustManager initialization routine in Listing 2.)
  • If you already have a signed certificate available, for example one managed by Netscape Navigator or Internet Explorer, you don't need to generate an extra one. Simply export that certificate along with its private key to a PKCS#12 file to disk, and have that file act as your keystore. This works because JSSE has basic support for keystores of type pkcs12.
Finally, when running in a Windows 2000 environment, you can dynamically map client requests to Active Directory user accounts. The only hurdle to overcome in this scenario is that the PKCS#10 requests need to have additional parameters meaningful only to Active Directory and the Windows authentication subsystem - something beyond the scope of this article.

Step 3: Adding Certificate Authentication to SOAP
Next you must modify SSLUtils.java to use your key during socket creation. The goal here is to create an SSLSocketFactory that will create sockets that will use your key for authentication during the handshake process. This involves a bit more canonical code that, like SSLUtils.java, can be found in the JSSE samples. To compile and test the changes, you'll need to unpack the SOAP JAR and sources.

Be sure to remove the SOAP JAR from your CLASSPATH and anywhere else you might find it, such as the lib\ext directory of the JDK or JRE you're using, while simultaneously making sure the servlet container can still find it. The modified org.apache.soap.util.net.SSLUtils is in Listing 3. Place it in the correct directory and recompile. Also, uncomment the lines in TestMain.java designated for Step 3.

If all is well, and you broke the example by requiring client certificates as suggested at the end of Step 1, the example should start working again.

How? Well, looking at the enableCerts() method that has been added to SSLUtils, you can see how the SSLSocketFactory is set up. The first step gets an instance of an SSLContext that implements the TLS protocol (Transport Layer Security - more info at ftp://ftp.isi.edu/in-notes/rfc2246.txt).

Next, the code gets a KeyManagerFactory and a keystore. The keystore instance is used to load the keystore created in Step 2. Then, to make explicit what's happening, the code gets an instance of the default TrustManager pointing to the default CA trust keystore cacerts. Note, though, that the default trust manager provides only very basic X.509-based certification path validity checking; it does not, for instance, check for certificates that have been revoked.

Then the KeyManagerFactory is initialized with the keystore, passing along the passphrase to use with the keys in the keystore. That's right - when using the default KeyManagerFactory, all keys in a given keystore that will be used for authentication must use the same passphrase. The code then initializes the SSLContext with the KeyManagers derived from the KeyManagerFactory and the TrustManager from above, and then gets an SSLSocketFactory from the context.

It seems like a lot of magic words, but in the end, you've added certificate-based authentication with about 10 lines of code. If the client, using a socket created by this factory, is challenged to authenticate during the handshake, the SSLSocketFactory will request an appropriate key from the KeyManagers to complete that portion of the handshake. Appropriate in this context means any certificate on the client that has been signed by a CA trusted by the server; if more than one client certificate fits the bill, the default KeyManager will simply pick the first one available.

This will provide you with perimeter security. For finer control, you'll need to get the client's identity back to the services. To do this, we refer you to Mark Moore's article in the premier issue of Web Services Journal: "Sending Out-of-Band Messages to SOAP-Based Web Services." The technique described extends the SOAP RPCRouterServlet servlet to add information to an InheritableThreadLocal, making it accessible to the service. In this case, you would want to include the value of HttpServletRequest.getRemoteUser() to the ServiceContext described in that article.

A Note About Performance
Why is it so slow? Well, there are a number of things going on. First, just cranking up the JVM can take a while. Also, the first time you create a socket, a java.security.SecureRandom object must be generated. That takes time, but it's only once. One way to avoid that is to generate one ahead of time, and supply it as the third argument to the SSLContext.init() method. The nature of this example does not allow that particular optimization.

Finally, HTTPS is simply going to be slower than an HTTP connection - establishing a connection takes time, as does encrypting the ongoing traffic. If you believe connection setup represents a significant impact on the performance of your system, you may want to investigate getting rid of the overhead of setting up a connection for every request by implementing HTTP "keep-alive". Since SOAP sends an HTTP version of "1.0", you would need to send a header in the form "Connection: keep-alive".

Assuming your Web server supports HTTP 1.1 (where keep-alive is implicit) or the keep-alive header with HTTP 1.0, you will be able to get a persisted connection to the server and reuse the socket that has already been set up. The hard part is altering HTTPUtils to take advantage of this persisted connection. If HTTPUtils used a java.net.HttpURLConnection, you might have gotten this for free, though this incurs other challenges - the handling of the HTTP error code 500, which is used by SOAP, being one of them.

As it is, HTTPUtils opens and closes a fresh socket every time and implements the POST as custom code, making the implementation of keep-alive not as straightforward as you might hope.

Terra Firma
You will certainly find opportunities to extend this basic example to suit your own requirements, but this should provide you with the grounding you need to get started. In addition to keep-alive, which has already been discussed, obvious enhancements would also include making the key alias and passphrase connection-based, perhaps using the existing setUserName() and setPassword(), and adding a setAuthenticationType().
We hope your interest is piqued to learn more about public key cryptography and its use in building secure systems. The subject area is deep and your planning will benefit from an understanding of the tools at your disposal. Though not yet mature, the technology is there to build robust and secure SOAP-based Web services.

The views and opinions are those of the authors and do not necessarily represent the views and opinions of KPMG LLP.

More Stories By Mark Moore

Mark Moore is currently an independent consultant. Previously, he was
Chief Architect for KPMG International's Global Knowledge Exchange,
deploying knowledge sharing capabilities to 80,000 KPMG employees in more
than 40 countries. He has been designing and developing web-based knowledge
management and collaborative solutions for the last six years.

More Stories By Adrian Turtschi

Adrian Turtschi is a software architect with KPMG's Global Knowledge Exchange in Boston. He is
interested in questions of interoperability and cross-platform development. He is currently working
on an authentication and authorization scheme for KPMG International.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
Digital Transformation and Disruption, Amazon Style - What You Can Learn. Chris Kocher is a co-founder of Grey Heron, a management and strategic marketing consulting firm. He has 25+ years in both strategic and hands-on operating experience helping executives and investors build revenues and shareholder value. He has consulted with over 130 companies on innovating with new business models, product strategies and monetization. Chris has held management positions at HP and Symantec in addition to ...
Dynatrace is an application performance management software company with products for the information technology departments and digital business owners of medium and large businesses. Building the Future of Monitoring with Artificial Intelligence. Today we can collect lots and lots of performance data. We build beautiful dashboards and even have fancy query languages to access and transform the data. Still performance data is a secret language only a couple of people understand. The more busine...
DXWorldEXPO LLC announced today that Big Data Federation to Exhibit at the 22nd International CloudEXPO, colocated with DevOpsSUMMIT and DXWorldEXPO, November 12-13, 2018 in New York City. Big Data Federation, Inc. develops and applies artificial intelligence to predict financial and economic events that matter. The company uncovers patterns and precise drivers of performance and outcomes with the aid of machine-learning algorithms, big data, and fundamental analysis. Their products are deployed...
All in Mobile is a place where we continually maximize their impact by fostering understanding, empathy, insights, creativity and joy. They believe that a truly useful and desirable mobile app doesn't need the brightest idea or the most advanced technology. A great product begins with understanding people. It's easy to think that customers will love your app, but can you justify it? They make sure your final app is something that users truly want and need. The only way to do this is by ...
The challenges of aggregating data from consumer-oriented devices, such as wearable technologies and smart thermostats, are fairly well-understood. However, there are a new set of challenges for IoT devices that generate megabytes or gigabytes of data per second. Certainly, the infrastructure will have to change, as those volumes of data will likely overwhelm the available bandwidth for aggregating the data into a central repository. Ochandarena discusses a whole new way to think about your next...
CloudEXPO | DevOpsSUMMIT | DXWorldEXPO are the world's most influential, independent events where Cloud Computing was coined and where technology buyers and vendors meet to experience and discuss the big picture of Digital Transformation and all of the strategies, tactics, and tools they need to realize their goals. Sponsors of DXWorldEXPO | CloudEXPO benefit from unmatched branding, profile building and lead generation opportunities.
Cell networks have the advantage of long-range communications, reaching an estimated 90% of the world. But cell networks such as 2G, 3G and LTE consume lots of power and were designed for connecting people. They are not optimized for low- or battery-powered devices or for IoT applications with infrequently transmitted data. Cell IoT modules that support narrow-band IoT and 4G cell networks will enable cell connectivity, device management, and app enablement for low-power wide-area network IoT. B...
The hierarchical architecture that distributes "compute" within the network specially at the edge can enable new services by harnessing emerging technologies. But Edge-Compute comes at increased cost that needs to be managed and potentially augmented by creative architecture solutions as there will always a catching-up with the capacity demands. Processing power in smartphones has enhanced YoY and there is increasingly spare compute capacity that can be potentially pooled. Uber has successfully ...
SYS-CON Events announced today that CrowdReviews.com has been named “Media Sponsor” of SYS-CON's 22nd International Cloud Expo, which will take place on June 5–7, 2018, at the Javits Center in New York City, NY. CrowdReviews.com is a transparent online platform for determining which products and services are the best based on the opinion of the crowd. The crowd consists of Internet users that have experienced products and services first-hand and have an interest in letting other potential buye...
When talking IoT we often focus on the devices, the sensors, the hardware itself. The new smart appliances, the new smart or self-driving cars (which are amalgamations of many ‘things'). When we are looking at the world of IoT, we should take a step back, look at the big picture. What value are these devices providing. IoT is not about the devices, its about the data consumed and generated. The devices are tools, mechanisms, conduits. This paper discusses the considerations when dealing with the...