Skip to content

Latest commit

 

History

History
78 lines (61 loc) · 3.81 KB

File metadata and controls

78 lines (61 loc) · 3.81 KB

XML Signature (XML-DSig)

status profile

Sign and verify FundsXML with enveloped XML Digital Signatures. All stacks use the same profile so signed files cross-verify between them:

Property Value
Signature method RSA-SHA256
Digest SHA-256
Canonicalization Exclusive C14N (xml-exc-c14n#)
Transform enveloped-signature + exclusive C14N
Reference URI="" (whole document)
KeyInfo signer X.509 certificate embedded
Placement ds:Signature is the last child of <FundsXML4> — exactly where the 4.2.9 schema allows it (xmldsig-core-schema.xsd import)

A signed file stays XSD-valid (verified) and matches the structure of the committed FundsXML_Files/4.2.9/signed/Signed_Fund_Skeleton.xml placeholder.

Keys

./mvnw -q -pl XML_Signature/java compile exec:java -Dexec.mainClass=GenerateTestKey
# -> XML_Signature/keys/ (gitignored).  Windows: use mvnw.cmd

GenerateTestKey uses the JDK's own keytool (no openssl, so it works on Windows too) to write a throwaway self-signed RSA-2048 keystore test-signing.p12 (alias fundsxml, pass changeit) and the PEM certificate test-signing-cert.pem. Demo only — never commit private keys.

Stacks

Stack Entry point Status
Java — Apache Santuario java/SignFundsXml.java / java/VerifyFundsXml.java ✅ verified (sign, verify, tamper-detect)
CLI — xmlsec1 cli/sign-verify-xmlsec1.sh ✅ verified (xmlsec1 1.2.33, in CI): sign, verify, tamper; cross-verifies with Java and .NET both ways
Python — signxml python/sign_verify_signxml.py reference (pip install -e ".[signature]" adds signxml)
.NET — SignedXml dotnet/SignVerify.cs verified (.NET SDK 8): sign, verify, tamper; cross-verifies with Java both ways

Run (Java / Apache Santuario — verified)

Standalone & cross-platform via the committed Maven Wrapper (./mvnw, or mvnw.cmd on Windows), from the repo root — xmlsec comes from Maven Central:

M="./mvnw -q -pl XML_Signature/java compile exec:java"

# one-off: throwaway key (JDK keytool, no openssl)
$M -Dexec.mainClass=GenerateTestKey

# sign
$M -Dexec.mainClass=SignFundsXml \
   -Dexec.args="FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml signed.xml \
                XML_Signature/keys/test-signing.p12 changeit fundsxml"

# verify — pin the signer cert (don't trust only the embedded key)
$M -Dexec.mainClass=VerifyFundsXml \
   -Dexec.args="signed.xml XML_Signature/keys/test-signing-cert.pem"

VerifyFundsXml exits 0 on a valid signature, 1 on tamper/failure (verified: flipping one digit in a signed file → INVALID). Santuario verification runs with secure validation enabled.

Note on xmlsec1: it signs an existing ds:Signature template, so it pairs naturally with the committed signed skeleton (FundsXML_Files/4.2.9/signed/Signed_Fund_Skeleton.xml); the Java/.NET/Python examples instead build and append the ds:Signature themselves. The skeleton's template carries exactly the profile above (exclusive C14N, enveloped + exc-C14N transforms, RSA-SHA256, empty X509Certificate placeholder that xmlsec1 fills), so the signed result verifies in Java and .NET both pinned and from the embedded certificate, and xmlsec1 verifies the Java/.NET output.

A real signed file is not committed — the signature is bound to the throwaway key, which is regenerated per run. CI signs → verifies as a roundtrip.