Differences between revisions 20 and 21
Revision 20 as of 2007-05-22 08:49:14
Size: 16011
Revision 21 as of 2009-09-20 22:47:58
Size: 16045
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 10: Line 10:
 1. [#isWSS4J What is WSS4J?]
[#isWSS4Jnot What is WSS4J not?]
 1. [#common
Encryption, decryption, signature, certificates, ...]
 1. [#parameters
Where can i get info on the parameters for WSS4J handlers?]
[#sigverify Problems and errors with Signature verification]
 1. [#noalgo
No such algorithm: http://www.w3.org/2001/04/xmlenc#rsa-1_5 or similar]
 1. [#npe
Spurious Null Pointer Exception]
[#debug Where can I change the debug level of wss4j?]
 1. [#many
I have many clients and one service (and I need signature+encryption). Is there a way to handle many client certs?]
 1. [#usernme
How can a Web Service check and access the results of security actions?]
 1. [#time
Timestamp handling in WSS4J]

 1. [[#isWSS4J|What is WSS4J?]]
 1. [
[#isWSS4Jnot|What is WSS4J not?]]
 1. [[#common|
Encryption, decryption, signature, certificates, ...]]
 1. [[#parameters|
Where can i get info on the parameters for WSS4J handlers?]]
 1. [
[#sigverify|Problems and errors with Signature verification]]
 1. [[#noalgo|
No such algorithm: http://www.w3.org/2001/04/xmlenc#rsa-1_5 or similar]]
 1. [[#npe|
Spurious Null Pointer Exception]]
 1. [
[#debug|Where can I change the debug level of wss4j?]]
 1. [[#many|
I have many clients and one service (and I need signature+encryption). Is there a way to handle many client certs?]]
 1. [[#usernme|
How can a Web Service check and access the results of security actions?]]
 1. [[#time|
Timestamp handling in WSS4J]]

Line 25: Line 25:
WSS4J is part of the Apache Web Services project. Here is [http://ws.apache.org/ link] to all Apache Web Service projects. WSS4J is part of the Apache Web Services project. Here is [[http://ws.apache.org/|link]] to all Apache Web Service projects.
Line 36: Line 36:
Here is the [http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss link] to Here is the [[http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss|link]] to
Line 39: Line 39:
[[Anchor(isWSS4Jnot)]] <<Anchor(isWSS4Jnot)>>
Line 45: Line 45:
[[Anchor(common)]] <<Anchor(common)>>
Line 49: Line 49:
[http://httpd.apache.org/docs/2.0/ssl/ssl_intro.html this text]. At the reference [[http://httpd.apache.org/docs/2.0/ssl/ssl_intro.html|this text]]. At the reference
Line 52: Line 52:
[[Anchor(parameters)]] <<Anchor(parameters)>>
Line 54: Line 54:
[http://wiki.apache.org/ws/FrontPage/WsFx/wss4jParameters Sample Parameters for WSS4J handlers]

[[http://wiki.apache.org/ws/FrontPage/WsFx/wss4jParameters|Sample Parameters for WSS4J handlers]]

Line 72: Line 72:
refer to [http://www.w3.org/TR/xml-c14n Canonical XML]. refer to [[http://www.w3.org/TR/xml-c14n|Canonical XML]].
Line 85: Line 85:
[[Anchor(noalgo)]] <<Anchor(noalgo)>>
Line 100: Line 100:
[[Anchor(npe)]] <<Anchor(npe)>>
Line 134: Line 134:
[[Anchor(debug)]] <<Anchor(debug)>>
Line 143: Line 143:
[http://logging.apache.org/ Apache logging] project.

[[http://logging.apache.org/|Apache logging]] project.

Line 192: Line 192:
[[Anchor(usernme)]] <<Anchor(usernme)>>
Line 260: Line 260:
[[Anchor(time)]] <<Anchor(time)>>

The FAQ for WSS4J

In the FAQ we try to gather a set of frequently asked questions and the answers to them.

This FAQ is a living page, please feel free to add new items to it if you feel that this information is worth to share with your fellow WSS4J users.

  1. What is WSS4J?

  2. What is WSS4J not?

  3. Encryption, decryption, signature, certificates, ...

  4. Where can i get info on the parameters for WSS4J handlers?

  5. Problems and errors with Signature verification

  6. No such algorithm: http://www.w3.org/2001/04/xmlenc#rsa-1_5 or similar

  7. Spurious Null Pointer Exception

  8. Where can I change the debug level of wss4j?

  9. I have many clients and one service (and I need signature+encryption). Is there a way to handle many client certs?

  10. How can a Web Service check and access the results of security actions?

  11. Timestamp handling in WSS4J

What is WSS4J?

WSS4J is part of the Apache Web Services project. Here is link to all Apache Web Service projects.

Apache WSS4J is an implementation of the OASIS Web Services Security specifications (WS-Security, WSS) from OASIS Web Services Security TC. WSS4J is primarily a Java library that can be used to sign, verify, encrypt, and decrypt SOAP Messages according to the WS-Security specifications. This library is independent of underlying SOAP engines. The link between WSS4J and SOAP engines is provided by handlers.

On top of this library we also implemented handlers for the Axis SOAP engine and for OAP engines that use JAX-RPC specifications.

Here is the link to the OASIS WS-Security specifications.

What is WSS4J not?

WSS4J is not a tool to

  • manage certificates or create certificates
  • encrypt, decrypt, sign, and verify arbitray XML documents

Encryption, decryption, signature, certificates, ...

This is what WSS4J is all about. To use WSS4J you shall have at least a basic understanding of all this. For a very first start have a look into this text. At the reference section you'll find more pointers to the relevant standards and other information.

Where can i get info on the parameters for WSS4J handlers

Sample Parameters for WSS4J handlers

Problems and errors with Signature verification

In this case you often an error or waring message similar to this one:

08:24:58,371 WARN  [Reference] Verification failed for URI "#id-22221245"
org.apache.ws.security.WSSecurityException: The signature verification failed
       at org.apache.ws.security.WSSecurityEngine.verifyXMLSignature(WSSecurity

Most often this problem occurs if the request message was modified after it was signed. Mostly this is due to some pretty printing where the request message was modified to look nicer. This pretty printing inserts newlines, blanks and tabs. Very often people think that these additional charaters are removed by canonicalization (c14n) of the message. This is a common misunderstanding.

C14n does not remove these newlines or other significant whitespace. For more information on c14n refer to Canonical XML.

Another very common cause of this error is forgetting to turn off namespace optimisation in your WSDD file. You need a line like this:

   <parameter name="enableNamespacePrefixOptimization" value="false" />

Leaving namespace optimisation on will cause axis to modify the signed message, invalidating the signature, if the message is not exactly in axis's preferred format. This prevents interoperability with other systems, such as .NET's WSE implementation.

No such algorithm: http://www.w3.org/2001/04/xmlenc#rsa-1_5 or similar

In most case this is a problem of a security provider. Depending on the used Java SDK several problems may show up:

  • Check if you have the full strengt encryption policy installed. By default only the limited one is installed (please refer to Sun's Java documentation how to get the full strength policy).
  • The Bouncycastle JAR is not in the Path of the server Web application. If WSS4J does not find the Bouncycastle in the classpath it is not initialized and registered as security provider. The standard Sun security provider does not support all requiered algorithms and keystore formats.

Other Java SDKs also may have problems to initialize and install the correct security provider.

Spurious Null Pointer Exception

Sometimes we get reports about a Null Pointer Exception (NPE) during WSS4J processing. In many cases this is due to a non namespace aware XML parser. Sun's Java 1.4.x uses the Crimson XML parser as default parser. This parser has problems supporting namespaces.

If you have a NPE please check the stacktrace if you find a class similar to org.apache.crimson.tree.ElementNode2. In this case you use the Crimson parser. Please make sure that a full namespace aware parser is in the classpath, e.g. Apache Xerces. Of course this is also true for other parsers that do not support XML namespace.

There is also a NullPointerException you can get that doesn't contain "crimson" anywhere. The top of the stack-trace looks like this:

WSHandler: Signature: error during message procesing... 
Signature creation failed; nested exception is: 
  java.lang.NullPointerException; nested exception is: 
  org.apache.ws.security.WSSecurityException: ...: Signature creation failed; nested exception is: 
  at org.apache.ws.axis.security.WSDoAllSender.invoke(WSDoAllSender.java:201)
  at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
 ...nested exception is: 
  at org.apache.ws.security.handler.WSHandler.performSIGNAction(WSHandler.java:203)

To determine what JAXP implementation is being loaded use the following code:


and if the class name isn't org.apache.xerces.jaxp.DocumentBuilderFactoryImpl then the Xerces jar isn't in your classpath (or it's being masked by the javax.xml.parsers.DocumentBuilderFactory System property or another JAXP-enabled XML parser on the classpath or the JRE/lib/jaxp.properties file).

Where can I change the debug level of wss4j?

The WSS4J functions and handlers use log4j to output debug and other messages during runtime. To control the output level, the output target, and the output format use the standard log4j property file. The src directory contains a predefined log4j.properties file that you can take as an example.

In this property file just enable the modules you would like to trace and put the file into the classpath. For more detailed information about log4j please refer to the Apache logging project.

I have many clients and one service (and I need signature+encryption). Is there a way to handle many client certs?

Each client has its own certificate, the requests shall be signed and encrypted. The responses also signed and encrypted.

Well, to keep the effort of the certificate adminsitration low I usually use the following technique. Using this way no special programming on the client or service is required, all handled via standard deployment.

Client part, request:

  • set up the client to use Binary Security Token (BST) when signing:
     <parameter name="signatureKeyIdentifier" value="DirectReference" />
    In this way the request contains the client's certificate, i.e. its public key. Because the certificate is included in the request the server does not need to store the certificate of every client.
  • Use the server's certificate (the public key) to perform request encryption.

Server part, request:

  • The handler (WSDoAllReceiver/WSSecurityEngine)) extracts the client's certificate from the request (because it's a Binary Security Token). Use this certificate to verfiy and perform trust verification agains the root certificate (certificate of the Certificate Authority, CA). The current verifyTrust implemetation requires to have all client certificates in the keystore to provide a better security/trust check against phony DNs and possible other mismatches.

  • the handler stores the extracted client certificate in the message context. This is transparent to the client and server code.

Server part, response:

  • To perform signing the server uses its private key to sign. You may use BST or some other way to identify the server's certificate. Every client needs to have the server's certificate anyway if you encrypt the request (see above).
  • To perform response encryption set the encryption user name to "useReqSigCert". This is a special name

    that directs the WSDoAllSender handler to use the stored client's certificate (the clients public key) to perform response encryption.

Client part, response:

  • nothing special, just set up the response stream correctly in the client's WSDD file.

As pointed out, usually no modification in client/service coding is necessary, also no need to change the trust handling inside WSDoAllReceiver except that you need a very special certificate trust verification.

How can a Web Service check and access the results of security actions?

MessageContext msgContext = MessageContext.getCurrentContext();
Vector results = (Vector) msgContext.getProperty(WSHandlerConstants.RECV_RESULTS);
log.trace("Potential number of usernames: " + results.size());
for (int i = 0; results != null && i < results.size(); i++) {
    WSHandlerResult hResult = (WSHandlerResult) results.get(i);
    Vector hResults = hResult.getResults();
    for (int j = 0; j < hResults.size(); j++) {
        WSSecurityEngineResult eResult = (WSSecurityEngineResult) hResults.get(j);
        // An encryption or timestamp action does not have an associated principal,
        // only Signature and UsernameToken actions return a principal
        if ((eResult.getAction() == WSConstants.SIGN)
            || (eResult.getAction() == WSConstants.UT)) {
            // Signature and UsernameToken actions return a principal
            System.out.println("Principal's name: " + eResult.getPrincipal().getName());
        } else if (eResult.getAction() == WSConstants.ENCR) {
            // Encryption action returns what ?
        } else if (eResult.getAction() == WSConstants.TS) {
            // Timestamp action returns a Timestamp
            System.out.println("Timestamp created: " + eResult.getTimestamp().getCreated());
            System.out.println("Timestamp expires: " + eResult.getTimestamp().getExpires());

The getter methods of WSSecurityEngineResult are depreciated. The new version of WSSecurityEngineResult inherits from Java's HashMap. Web Services shall use the standard get() to retrieve data from WSSecurityEngineResult (see examples below).

The WSS4J handler stores the results in the Axis message context.

At first the web service fetches the vector that contains the results of all WSS4J handler invocations for a request. There maybe several invocation (chained handlers) because a request may contain several security elements for different actors.

The web service may check the actor's name in each WSHandlerResult using getActor() (not show above). If the actor's name matches or if this is the only handler result object the web service can check the result of each security action.

The web service gets the vector of the security results from the handler result using getResults(). This vector contains a number of WSSecurityEngineResult objects that contain further information for each performed secutity action.


To get a principal:

java.security.Principal principal = (java.security.Principal)eResult.get(WSSecurityEngineResults.TAG_PRINCIPAL);

At this point the Web Service may check the principal's type, depending on the security action (see above). To get the action

int action = ((java.lang.Integer)eResult.get(WSSecurityEngineResults.TAG_ACTION)).intValue()

Accessible data in WSSecurityEngineResult depending on security actions

For Signatures the WSSecurityEngineResult map contains:

  • The principal that signed the request, for example the distinguished name

    of the certificate, the SUsernameTokenPrincipal, or the WSDerivedKeyTokenPrincipal. This depends on the request.

  • The certificate used to sign the request if it is a request according to the WS X.509 profile, not used otherwise
  • The Set of elements that this Signature covers
  • A byte array that contains the Signature value

The web service can access these data using getter methods (deprectiated) or standard HashMap get methods. See the Javadoc documentation of WSSecurityEngineResults.

Timestamp handling in WSS4J

WSS4J supports several time features and options. If you just use the action Timestamp without any further configuration WSS4J uses the following defaults:

  • All timestaps use millisecond precision
  • The default time difference between Created and Expires is set to 300 seconds (5 minutes).

  • The handler performs strict timestamp handling, i.e. throws an exception if verification of the timestamp fails.

Use the following handler parameters to change these settings:

  • timeToLive to specify another time difference between Created and Expires. The value of this parameter is an integer that defines the time difference in seconds.

  • precisionInMilliseconds to switch off the millisecond time precision. Set the value to false or 0 to generate timestamps without milliseconds.

  • timestampStrict to switch off strict timestamp handling. Set the value to false or 0 to switch off strict handling. According to WSS specfications it is optional to report a fault if timestamp verification fails.

WSS4J uses the UTC timezone (zulu time) to generate timestamps. This is according to the WSS specifications.

At the receiving end WSS4J checks if the request is still valid (is not expired). This is done in two steps:

  • In the first step the WSSecurityEngine (WSS4J 1.x.y) or the TimestampProcessor (since WSS4J 2.x.x) checks the Expires timestanp against the server's current time. If this check fails then then handler throws an exception if strict timestamp handling is on.

  • In the second step the WSS4J handler, either WSDoAllReceiver or WSS4JHandler, performs a check based on server information. The server computes a valid creation time by subtracting the time-to-live from the current time at the server and checks the Created time aginst this computed value. The default time-to-live value is 300 seconds. You may specify a timeToLive parameter in the handler's request path at the server to define another value for the time difference. This handler perfoms this check only if strict timestamp handling is on.

FrontPage/WsFx/wss4jFAQ (last edited 2009-09-20 22:47:58 by localhost)