This is an eXist-db implementation of the EXPath HTTP Crypto Module specification.
Requires:
- Java 21 or newer
- Maven 3.9 or newer
$ git clone https://github.com/eXist-db/expath-crypto-module.git
$ cd expath-crypto-module
$ mvn clean packageThis will create a "expath-crypto-module-.xar" file in the target folder. The .xar file can be uploaded to any eXist-db version > 7.0.0-SNAPSHOT via the Dashboard.
- crypto:hash()
- crypto:hmac() (only for xs:string data for now)
- crypto:encrypt() (only for xs:string data and symmetric encryption for now)
- crypto:decrypt() (only for xs:string data and symmetric decryption for now)
- crypto:generate-signature() (only for XML data for now)
- crypto:validate-signature() (only for XML data for now)
- For crypto:hash(): "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512".
- For crypto:hmac(): "HMAC-MD5", "HMAC-SHA-1", "HMAC-SHA-256", "HMAC-SHA-384", "HMAC-SHA-512".
For the latest version of the specification for this module see http://expath.org/spec/crypto/editor.
The implementation follows this specification.
The crypto module is a security-sensitive library and operates on XML documents that may come from untrusted sources. A few things to know when deploying or auditing it:
-
XXE protection lives in this module, not in
conf.xml. eXist-db's<validation>configuration inconf.xmlcontrols catalog resolution and validation mode, not entity processing. eXist hardens its own parsers by callingsetFeature("...external-general-entities", false)etc. at each call site in Java code. The crypto module uses its ownDocumentBuilderFactory/SAXParserFactoryinstances (centralised inorg.expath.exist.crypto.utils.SecureXmlParsers), and does not inherit those settings. Both signature paths now refuse DOCTYPE declarations outright (disallow-doctype-decl=true), which is the OWASP-recommended baseline. A strictconf.xmldoes not, on its own, protect callers ofcrypto:generate-signatureorcrypto:validate-signatureagainst XXE. The doctype gate is currently hardcoded — we're being conservative for this hardening round — and is open to follow-on PRs that expose an opt-out (for example, an extra parameter or a module-level toggle) for callers who legitimately need to validate signed documents that carry a DOCTYPE declaration. -
Signature algorithms are limited to SHA-1-based xmldsig methods (
RSA_SHA1,DSA_SHA1) by the underlyingcrypto-javalibrary, which has not been updated to support SHA-256. JDK 17+ rejects these by default underorg.jcp.xml.dsig.secureValidation— see the JDK XML Signature security guide for the policy. Don't sign new documents with these algorithms in production. -
Symmetric encryption uses CBC (or unprefixed
AES, which defaults to ECB) without authentication. There is no AEAD (e.g. AES-GCM) support, and the module performs no HMAC-then-encrypt or encrypt-then-HMAC pairing. Ciphertext integrity is the caller's responsibility — without it, CBC is vulnerable to padding-oracle attacks, and ECB leaks plaintext structure. -
Constant-time comparison is the caller's responsibility. XQuery's
=operator is not constant-time. When comparing HMAC outputs or signature values, an attacker who can measure timing can recover bytes. There is nocrypto:verify-hmachelper that compares in constant time; callers should treat HMAC verification as a known sharp edge.
If you find what you believe is a security issue, please follow the eXist-db security policy rather than opening a public issue.
Unit Tests use XQSuite and can be found in the src/test/xquery/crypto folder.
To run tests:
$ mvn verify