1) Serializers in Apache Santuario
The XMLCipher class in Santuario is the main entry point for encryption and decryption. The XMLCipher class makes use of the Serializer interface to serialize DOM elements to byte arrays for encryption, and to deserialize byte arrays to DOM elements for decryption. Santuario ships with two different implementations. The default is TransformSerializer, which makes use of the "javax.xml.transform.Transformer" API and requires Apache Xalan to work properly. The other alternative is the DocumentSerializer, which uses the standard DOM API. These implementations perform very similarly.
Apache CXF is a web services framework that heavily leverages Apache Santuario to perform XML encryption and decryption of web service messages. CXF is fully streaming based and so it made sense to look to re-use some of this functionality with a custom Serializer implementation. The result is the StaxSerializer. This largely re-uses the DOM implementation for encryption, but uses a streaming based approach for deserialization. StaxSerializer is used by default in Apache CXF when working with XML encryption/decryption.
2) Benchmarking
To benchmark the StaxSerializer, I adapted the Santuario benchmarking test-suite just to compare encryption performance using the different Serializers, and put it into github here:
- santuario-serializer-benchmark: This project contains two Junit tests used for benchmarking XML Encryption. In particular, they measure memory and timing performance for both encryption and decryption, ranging from small to very large XML files.
Here is the result for the (default) TransformSerializer:
In comparison, here is the result for the StaxSerializer:
The most obvious conclusion is that the streaming API is far more efficient in terms of memory consumption, especially when we scale to larger documents. However one would expect also to see less memory being consumed using the StaxSerializer compared to the TransformSerializer. Indeed, one can see that the TransformSerializer almost consumes 600MB for the largest case, wheras the StaxSerializer comes in under 450MB.
b) Time needed for decryption
Turning now to execution time, here is the result for the (default) TransformSerializer:
As stated above, the performance is fairly identical to the streaming layer. This is because the streaming implementation needs to make several passes of the XML for consistency reasons. Here is the result for the StaxSerializer:
Here we can see that the StaxSerializer actually offers superior performance to the streaming API. So if XML decryption performance is an issue for you, it might be worth considering using CXF's StaxSerializer.