Python bindings for Bergshamra XML Security (XML-DSig, XML-Enc, C14N)
Project description
pybergshamra
Python bindings for the Bergshamra XML Security library -- a pure-Rust implementation of XML Digital Signatures (XML-DSig), XML Encryption (XML-Enc), C14N canonicalization, and cryptographic primitives.
pybergshamra gives you a fast, correct, and memory-safe XML security toolkit from Python with no C dependencies to compile and no transitive native libraries to audit.
Features
- XML Digital Signatures -- sign and verify (RSA, EC, Ed25519, HMAC, post-quantum)
- XML Encryption -- encrypt and decrypt (AES-CBC/GCM, RSA-OAEP key transport)
- C14N canonicalization -- inclusive, exclusive, with/without comments
- Key management -- RSA, EC, Ed25519, X25519, HMAC, AES, 3DES, PKCS#12, X.509
- Certificate validation -- X.509 chain building and verification with CRL support
- Cryptographic primitives -- digest, PBKDF2, HKDF, ConcatKDF
- Post-quantum signatures -- ML-DSA-44/65/87, SLH-DSA
- Anti-XSW protection -- strict verification mode
- Zero Python dependencies -- ships as a single native extension
Installation
python3 -m pip install pybergshamra
Or with uv:
uv add pybergshamra
Wheels are compiled from Rust via maturin. Python 3.10+ is required.
Quick start
Verify a signed XML document
import pybergshamra
xml = open("signed.xml").read()
manager = pybergshamra.KeysManager()
key = pybergshamra.load_x509_cert_pem(open("cert.pem", "rb").read())
manager.add_key(key)
ctx = pybergshamra.DsigContext(manager)
result = pybergshamra.verify(ctx, xml)
if result:
print("Valid!", result.key_info.algorithm)
else:
print("Invalid:", result.reason)
Sign an XML template
import pybergshamra
template = open("sign-template.xml").read()
manager = pybergshamra.KeysManager()
key = pybergshamra.load_rsa_private_pem(open("rsakey.pem", "rb").read())
manager.add_key(key)
ctx = pybergshamra.DsigContext(manager)
signed_xml = pybergshamra.sign(ctx, template)
Encrypt and decrypt
import pybergshamra
# Encrypt
manager = pybergshamra.KeysManager()
key = pybergshamra.load_x509_cert_pem(open("cert.pem", "rb").read())
manager.add_key(key)
ctx = pybergshamra.EncContext(manager)
encrypted_xml = pybergshamra.encrypt(ctx, template_xml, b"secret data")
# Decrypt
manager = pybergshamra.KeysManager()
key = pybergshamra.load_rsa_private_pem(open("rsakey.pem", "rb").read())
manager.add_key(key)
ctx = pybergshamra.EncContext(manager)
decrypted_xml = pybergshamra.decrypt(ctx, encrypted_xml)
Canonicalize XML
import pybergshamra
from pybergshamra import C14nMode
result = pybergshamra.canonicalize(xml_string, C14nMode.Exclusive)
Compute a digest
from pybergshamra import digest, Algorithm
h = digest(Algorithm.SHA256, b"hello world")
print(h.hex())
API overview
| Class / function | Purpose |
|---|---|
Algorithm |
W3C XML Security algorithm URI constants |
Key |
A cryptographic key (RSA, EC, HMAC, AES, Ed25519, etc.) |
KeyUsage |
Key usage mode (Sign, Verify, Encrypt, Decrypt, Any) |
KeysManager() |
Key store for managing keys and certificates |
DsigContext(manager) |
Configuration for XML-DSig sign/verify |
EncContext(manager) |
Configuration for XML-Enc encrypt/decrypt |
C14nMode |
Canonicalization mode (Inclusive, Exclusive, etc.) |
VerifyResult |
Result of signature verification |
verify(ctx, xml) |
Verify a signed XML document |
sign(ctx, template) |
Sign an XML template |
encrypt(ctx, template, data) |
Encrypt data with an XML template |
decrypt(ctx, xml) |
Decrypt an XML document |
canonicalize(xml, mode) |
Canonicalize an XML document |
digest(uri, data) |
Compute a message digest |
validate_cert_chain(...) |
Validate an X.509 certificate chain |
load_key_file(path) |
Load a key from file (auto-detect format) |
load_rsa_private_pem(data) |
Load an RSA private key from PEM |
load_x509_cert_pem(data) |
Load an X.509 certificate from PEM |
load_hmac_key(data) |
Create an HMAC key from raw bytes |
load_aes_key(data) |
Create an AES key from raw bytes |
load_pem_auto(data) |
Auto-detect PEM type and load |
See the full API reference for all 28 key loaders, algorithm constants, and configuration options.
Exceptions
| Exception | Raised when |
|---|---|
BergshamraError |
Base exception for all errors |
XmlError |
XML parsing or structure error |
CryptoError |
Cryptographic operation failure |
KeyLoadError |
Key loading failure |
AlgorithmError |
Unsupported algorithm |
EncryptionError |
Encryption/decryption failure |
CertificateError |
Certificate validation failure |
All exceptions inherit from BergshamraError, which inherits from Exception.
Migrating from python-xmlsec
pybergshamra (together with pyuppsala for XML building) is a complete replacement for python-xmlsec with zero C dependencies. See the migration guide for side-by-side examples.
Type stubs
A pybergshamra.pyi file is included for full IDE auto-completion and
type-checking with mypy/pyright.
Development
# Clone the repository
git clone https://github.com/kushaldas/pybergshamra.git
cd pybergshamra
# Set up the environment with uv
uv sync
# Build the native extension in development mode
uv run maturin develop
# Run the test suite
uv run pytest
# Build a release wheel
uv run maturin build --release
License
BSD-2-Clause
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pybergshamra-0.3.3.tar.gz.
File metadata
- Download URL: pybergshamra-0.3.3.tar.gz
- Upload date:
- Size: 75.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53ee613292b5cc8dbbba79927239680f9fbb4fd37dbd25dad2ca7b7ff148c193
|
|
| MD5 |
1cc128b6d70a5fc08cbe81a9a2e2248f
|
|
| BLAKE2b-256 |
6bf972ee9ded24edb2757d65bda3fc5da207bf4003a7dedeb44b63bd00be7ab3
|
Provenance
The following attestation bundles were made for pybergshamra-0.3.3.tar.gz:
Publisher:
release.yml on kushaldas/pybergshamra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pybergshamra-0.3.3.tar.gz -
Subject digest:
53ee613292b5cc8dbbba79927239680f9fbb4fd37dbd25dad2ca7b7ff148c193 - Sigstore transparency entry: 1050437511
- Sigstore integration time:
-
Permalink:
kushaldas/pybergshamra@f767382e5e21cf1e58b55c94afa9807b612f56bd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kushaldas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f767382e5e21cf1e58b55c94afa9807b612f56bd -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pybergshamra-0.3.3-cp310-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pybergshamra-0.3.3-cp310-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7df0b12b8edc7655fc48f5a4db36378d15cf54dc0abd88eba49081bae7618f9
|
|
| MD5 |
21b18ab6f4abb6bff5a8e61a7c3f6ed7
|
|
| BLAKE2b-256 |
1e97e60b4d7f73e4cd34dfa7b1112d10d0674063281f7f63adae0dfb8b040f3d
|
Provenance
The following attestation bundles were made for pybergshamra-0.3.3-cp310-abi3-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on kushaldas/pybergshamra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pybergshamra-0.3.3-cp310-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
a7df0b12b8edc7655fc48f5a4db36378d15cf54dc0abd88eba49081bae7618f9 - Sigstore transparency entry: 1050437583
- Sigstore integration time:
-
Permalink:
kushaldas/pybergshamra@f767382e5e21cf1e58b55c94afa9807b612f56bd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kushaldas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f767382e5e21cf1e58b55c94afa9807b612f56bd -
Trigger Event:
workflow_dispatch
-
Statement type: