{"library":"signxml","title":"signxml","description":"signxml is a Python library that implements the W3C XML Signature standard (XMLDSig), used for payload security in standards like SAML 2.0, XAdES, EBICS, and WS-Security. It provides features for signing and verifying XML documents, including support for X.509 certificate chains and XAdES signatures. The library is actively maintained with regular releases, supporting modern Python versions (3.9-3.13+).","language":"python","status":"active","last_verified":"Thu May 21","install":{"commands":["pip install signxml"],"cli":{"name":"signxml","version":"sh: 1: signxml: not found"}},"imports":["from signxml import XMLSigner","from signxml import XMLVerifier","from lxml import etree"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"from lxml import etree\nfrom signxml import XMLSigner, XMLVerifier, SignatureConfiguration\nimport os\n\n# --- Setup: Generate test certificate and key (requires OpenSSL) ---\n# openssl req -x509 -nodes -subj \"/CN=test\" -days 1 -newkey rsa -keyout privkey.pem -out cert.pem\n# In a real application, you would load these from secure storage.\n\n# Ensure cert.pem and privkey.pem exist in the current directory for this example to run.\nif not (os.path.exists('cert.pem') and os.path.exists('privkey.pem')):\n    print(\"Please generate 'cert.pem' and 'privkey.pem' using OpenSSL as described in the comments.\")\n    exit()\n\ncert = open(\"cert.pem\").read()\nkey = open(\"privkey.pem\").read()\n\n# --- Signing an XML document ---\ndata_to_sign = \"<Test><Data>Hello World!</Data></Test>\"\nroot = etree.fromstring(data_to_sign)\n\nsigner = XMLSigner()\nsigned_root = signer.sign(root, key=key, cert=cert)\n\nprint(\"\\n--- Signed XML ---\")\nprint(etree.tostring(signed_root, pretty_print=True).decode())\n\n# --- Verifying the signed XML document ---\nverifier = XMLVerifier()\n\ntry:\n    # It's crucial to explicitly provide the trusted certificate or CA for verification\n    # and to ensure the returned data is what was expected to prevent signature wrapping attacks.\n    verified_data = verifier.verify(signed_root, x509_cert=cert).signed_xml\n    \n    print(\"\\n--- Verification Successful! ---\")\n    print(\"Signed data content:\", etree.tostring(verified_data, pretty_print=False).decode())\n    \n    # Optionally, assert the signature location (best practice for SAML etc.)\n    config = SignatureConfiguration(location='./')\n    verifier.verify(signed_root, x509_cert=cert, expect_config=config)\n    print(\"Signature location asserted successfully.\")\n\nexcept Exception as e:\n    print(f\"\\n--- Verification Failed: {e} ---\")\n","lang":"python","description":"This quickstart demonstrates basic XML signing and verification using `XMLSigner` and `XMLVerifier`. It includes placeholder instructions for generating a test certificate and key using OpenSSL. In production, always load certificates and keys securely and explicitly configure trust for verification. It also highlights the best practice of verifying the `signed_xml` attribute and asserting the signature's expected location.","tag":null,"tag_description":null,"last_tested":"2026-04-25","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-21","installed_version":"4.4.0","pypi_latest":"4.4.0","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2.9,"avg_import_s":0.46,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.34,"mem_mb":10.5,"disk_size":"47.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.37,"mem_mb":10.5,"disk_size":"46.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.1,"import_time_s":0.24,"mem_mb":10.5,"disk_size":"47M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":10.5,"disk_size":"47M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.61,"mem_mb":11.3,"disk_size":"49.1M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.76,"mem_mb":11.3,"disk_size":"48.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.8,"import_time_s":0.57,"mem_mb":11.3,"disk_size":"49M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":11.3,"disk_size":"49M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.47,"mem_mb":11.3,"disk_size":"41.0M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":11.3,"disk_size":"40.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.4,"import_time_s":0.52,"mem_mb":11.3,"disk_size":"41M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.62,"mem_mb":11.3,"disk_size":"41M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.43,"mem_mb":11,"disk_size":"40.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":11,"disk_size":"40.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.4,"import_time_s":0.47,"mem_mb":11,"disk_size":"41M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":11,"disk_size":"41M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.32,"mem_mb":10.7,"disk_size":"47.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.37,"mem_mb":10.7,"disk_size":"47.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.6,"import_time_s":0.31,"mem_mb":10.7,"disk_size":"48M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"signxml","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.33,"mem_mb":10.7,"disk_size":"47M"}]}}