The existing Apache Santuario - XML Security for Java implementation is DOM-based. What this essentially means is that the complete XML Document must be read into memory before being signed or verified. For large XML Documents this carries a corresponding performance penalty. In addition, it means that XML Signature is not feasible for very large documents. In contrast, the StAX API uses a streaming approach, resulting in very low memory usage.
The streaming XML/WS-Security functionality is split between the Apache Santuario and WSS4J projects. The Apache Santuario project contains the core streaming capabilities for XML Signature and Encryption. The Apache WSS4J project builds on this functionality to deliver a streaming WS-Security stack. The entire streaming security functionality is the work of Marc Giger, who donated his SWSSF project to Apache. Marc has done an outstanding job to implement this technically difficult task, and also to integrate the functionality into existing Apache projects. If you wish to experiment with the new functionality, it is available via the 2.0.0-rc1 release.
1) XML Signature test-cases
In this post we will focus on XML Signature only. I have uploaded some test-cases to github to show how to use the new StAX-based API. There are currently three junit tests in this project:
- SignatureDOMTest - Sign + verify using the (older) DOM API
- SignatureStAXTest - Sign + verify using the new StAX API
- SignatureInteropTest - Test interop between the two implementations
To see how to configure the new outbound StAX-based XML Signature functionality, take a look at the "signUsingStAX" method used by the tests. The streaming XML Security functionality is configured by populating a XMLSecurityProperties Object. You must typically call the following methods:
- properties.setAction(XMLSecurityConstants.Action) - an "Action" to perform, which for XML Signature purposes is XMLSecurityConstants.SIGNATURE.
- properties.setSignatureKey(Key) - The signing key. Can be a PrivateKey or SecretKey.
- properties.setSigningCerts(X509Certificate[]) - The signing certs. May be inserted into the Signature KeyInfo depending on the Signature KeyIdentifier.
- properties.addSignaturePart(SecurePart) - Add a SecurePart to sign, e.g. sign a given QName. You can also specify a digest method or transform algorithm here. You can also sign the entire request via SecurePart.setSecureEntireRequest(boolean).
- properties.setSignatureAlgorithm(String) - Signature Algorithm to use. The default depends on the signing key.
- properties.setSignatureDigestAlgorithm(String) - Signature Digest Algorithm to use. The default is the URI for SHA-1.
- properties.setSignatureCanonicalizationAlgorithm(String) - The canonicalization algorithm to use. The default is XMLSecurityConstants.NS_C14N_EXCL_OMIT_COMMENTS.
- properties.setSignatureKeyIdentifier(SecurityTokenConstants.KeyIdentifier) - How to reference the signing key/cert. The default is SecurityTokenConstants.KeyIdentifier_IssuerSerial.
- SecurityTokenConstants.KeyIdentifier_KeyValue
- SecurityTokenConstants.KeyIdentifier_KeyName
- SecurityTokenConstants.KeyIdentifier_IssuerSerial
- SecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier
- SecurityTokenConstants.KeyIdentifier_X509KeyIdentifier
- SecurityTokenConstants.KeyIdentifier_X509SubjectName
- SecurityTokenConstants.KeyIdentifier_NoKeyInfo
3) Inbound StAX configuration
To see how to configure the new inbound StAX-based XML Signature functionality, take a look at the "verifyUsingStAX" method used by the tests. As with signature creation, it is necessary to create a XMLSecurityProperties Object, and to tell it what "Action" to perform. In addition you must call the following method, unless the complete signing key is contained in the Signature KeyInfo:
- properties.setSignatureVerificationKey(Key) - a key to use to verify the Signature.