Registry / auth-security / xmlsec

xmlsec

JSON →
library1.3.17pypypi✓ verified 25d ago

The `xmlsec` library provides Python bindings for the XML Security Library, enabling XML digital signatures, encryption, and other security operations on XML documents. It is actively maintained with frequent updates, often focused on ensuring compatibility with specific versions of the underlying `lxml` and `libxml2` libraries. The current version is 1.3.17.

pip install xmlsec
INSTALL
IMPORT
SIG · XMLSEC
X
xmlsec
auth-securitypythonv1.3.17
Install
2.2s avg
Import
53ms
Disk
40MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.3.17 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.056s · 41.7MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 2.2s · import 0.050s · 42MB
40MB installed
● package 40MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

xmlsec
import xmlsec
etree
from lxml import etree
While `xmlsec` can sometimes work with `xml.etree.ElementTree`, its full functionality, especially for signature context operations, is designed for `lxml.etree` elements.

This quickstart demonstrates how to digitally sign an XML document and then verify its signature using `xmlsec` and `lxml`. It involves creating an XML structure, adding a signature template, loading a private key and certificate, signing the document, and finally verifying the signature. Make sure to replace `private_key.pem` and `certificate.pem` with your actual key and certificate files in a production environment.

import xmlsec from lxml import etree import os # Initialize xmlsec library xmlsec.init() # Define paths for key and certificate files # In a real application, replace these with your actual key and cert paths. # For this example to run, ensure these files exist or create dummy ones: # Example: openssl genrsa -out private_key.pem 2048 # Example: openssl req -new -x509 -key private_key.pem -out certificate.pem -days 365 key_file = os.environ.get('XMLSEC_PRIVATE_KEY_PATH', 'private_key.pem') cert_file = os.environ.get('XMLSEC_CERTIFICATE_PATH', 'certificate.pem') # Basic check for dummy files for quickstart execution if not os.path.exists(key_file) or not os.path.exists(cert_file): print(f"Warning: '{key_file}' and '{cert_file}' not found. " "Please generate dummy key/cert files for this quickstart to run.") # Minimal dummy content for illustration, DO NOT USE IN PRODUCTION with open(key_file, 'w') as f: f.write("-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n") with open(cert_file, 'w') as f: f.write("-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n") try: # Create an XML document using lxml root = etree.Element("Data") etree.SubElement(root, "Item", id="item1").text = "Value1" # Add a signature template to the root element signature_node = xmlsec.template.add_signature(root, xmlsec.constants.TransformExclC14N) # Add SignedInfo element, reference the entire document signed_info_node = xmlsec.template.ensure_signed_info(signature_node, xmlsec.constants.TransformExclC14N, xmlsec.constants.TransformRsaSha1) xmlsec.template.add_reference(signed_info_node, xmlsec.constants.TransformSha1, uri="#xpointer(/)") # Add KeyInfo element with certificate key_info_node = xmlsec.template.ensure_key_info(signature_node) xmlsec.template.add_x509_data(key_info_node) xmlsec.template.add_x509_certificate(key_info_node) # Include the certificate itself # Create a KeysManager and load the private key for signing manager = xmlsec.KeysManager() signing_key = xmlsec.Key.from_file(key_file, xmlsec.KeyFormatPEM) # Add the certificate to the key object for inclusion in KeyInfo signing_key.add_cert_from_file(cert_file, xmlsec.KeyFormatPEM) manager.add_key(signing_key) # Create a SignatureContext and set the signing key ctx = xmlsec.SignatureContext(manager) ctx.key = signing_key # Sign the XML document print("Signing XML document...") ctx.sign(signature_node) signed_xml_str = etree.tostring(root, pretty_print=True, encoding='unicode') print("Signed XML:\n", signed_xml_str) # Verify the signature print("\nVerifying signature...") verify_ctx = xmlsec.SignatureContext(manager) # Use the same manager with loaded key/cert if verify_ctx.verify(signature_node): print("Signature is valid!") else: print("Signature verification FAILED.") finally: # Shutdown xmlsec library xmlsec.shutdown()
Debug
Known issues
breakingBinary wheels for `xmlsec` have strict version requirements for `lxml` due to shared underlying `libxml2`. Installing incompatible versions will lead to runtime errors like `ImportError: cannot import name _xmlsec from lxml.etree` or segfaults.
fix
Consult the `xmlsec` release notes for the exact `lxml` version required for your `xmlsec` version. For `xmlsec==1.3.17`, `lxml` must be `>= 6.0.2`. Pin `lxml` in your `requirements.txt` (e.g., `lxml>=6.0.2,<7.0`) to avoid conflicts.
affects: All versions 1.3.16+
gotchaWhen installing `xmlsec` from source (e.g., if no wheel is available for your platform/Python version), it requires the C libraries `libxml2` and `libxmlsec1` (including their development headers) to be installed on your system. Failure to do so will result in build errors.
fix
Install the necessary system packages. For Debian/Ubuntu: `sudo apt-get install libxml2-dev libxmlsec1-dev`. For Fedora/RHEL/CentOS: `sudo dnf install libxml2-devel xmlsec1-devel`.
affects: All versions when building from source
gotchaIt is crucial to initialize the `xmlsec` library by calling `xmlsec.init()` at the start of your application and to properly clean up resources by calling `xmlsec.shutdown()` before your application exits. Failing to do so can lead to memory leaks or undefined behavior.
fix
Always enclose your `xmlsec` operations within `xmlsec.init()` and `xmlsec.shutdown()` calls, ideally using a `try...finally` block to ensure `shutdown()` is called even if errors occur.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'xmlsec'
The `xmlsec` Python package is not installed in the active Python environment, or its installation failed previously due to missing system dependencies.
fix
Install `xmlsec` using `pip install xmlsec`. If compilation errors occur, first install required system development packages (e.g., `sudo apt-get install libxml2-dev libxmlsec1-dev pkg-config` on Debian/Ubuntu, `sudo yum install libxml2-devel xmlsec1-devel pkgconfig` on RHEL/CentOS, or `brew install libxml2 xmlsec1` on macOS).
xmlsec/src/xmlsec.h:4:10: fatal error: libxml/tree.h: No such file or directory
The `xmlsec` Python package requires the `libxml2` development headers to be installed on the system for compilation, specifically `libxml/tree.h`.
fix
Install the system-level development package for `libxml2` (e.g., `libxml2-dev` on Debian/Ubuntu, `libxml2-devel` on RHEL/CentOS, or `libxml2` on macOS via Homebrew). A common installation command for Linux is `sudo apt-get install libxml2-dev libxmlsec1-dev pkg-config`.
xmlsec/src/xmlsec.h:5:10: fatal error: xmlsec/xmlsec.h: No such file or directory
The `xmlsec` Python package requires the `libxmlsec1` development headers to be installed on the system for compilation, specifically `xmlsec/xmlsec.h`.
fix
Install the system-level development package for `libxmlsec1` (e.g., `libxmlsec1-dev` on Debian/Ubuntu, `xmlsec1-devel` on RHEL/CentOS, or `xmlsec1` on macOS via Homebrew). A common installation command for Linux is `sudo apt-get install libxml2-dev libxmlsec1-dev pkg-config`.
ImportError: cannot import name 'init' from 'xmlsec'
The functions `init` and `constants` (among others) were moved from the top-level `xmlsec` module to `xmlsec.core` in newer versions of the library.
fix
Update your import statements to import `init` (and `constants`) from `xmlsec.core`.

```python
# Before (incorrect)
# from xmlsec import init
# from xmlsec import constants

# After (correct)
from xmlsec.core import init
from xmlsec.core import constants
```
xmlsec.XMLSigError: XML Security Library is not initialized
The underlying XML Security Library has not been initialized by calling `xmlsec.core.init()` before performing any cryptographic operations.
fix
Call `xmlsec.core.init()` once at the start of your application before any other `xmlsec` operations.

```python
import xmlsec
from xmlsec.core import init, shutdown

init()
try:
    # Your xmlsec operations here
    pass
finally:
    shutdown() # Optional, but good practice if explicitly managing resources
```
Upgrade
Version history
1.3.17latest on PyPI · released Nov 11, 2025
Audit
Dependencies
lxmlrequiredCrucial for processing XML and generating/verifying signatures. Binary wheels for `xmlsec` have strict `lxml` version requirements due to shared underlying `libxml2`.
Agent activity
39 hits · last 30 days
node
32
OpenAI (training)
1
Resources
xmlsec — pip install xmlsec · libregistry