Enveloped vs Enveloping vs Detached XML Signatures
XML Digital Signatures (XMLDSig) provide data integrity,
authentication, and non-repudiation for digital assets. The XML standard
defines three primary signature types based on the structural
relationship between the <Signature> element and the
data being signed: enveloped,
enveloping, and detached. The
fundamental difference lies in whether the signature is contained within
the signed data, contains the signed data, or exists independently of
it.
Enveloped Signatures
In an enveloped signature, the <Signature> element
is nested inside the XML content that it signs. The signature is a child
element of the target data’s root element.
Because the signature is placed inside the data being signed,
calculating the cryptographic digest would create a circular dependency
(signing the signature itself). To resolve this, enveloped signatures
must use the standard enveloped-signature transform (a
specific XPath filter), which strips out the
<Signature> block before calculating the digest
value.
Structural Example
<RootDocument id="doc1">
<DataElement>Signed content goes here</DataElement>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:Reference URI="#doc1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<!-- Digest and algorithms -->
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
</ds:Signature>
</RootDocument>Enveloping Signatures
In an enveloping signature, the relationship is reversed: the
<Signature> element is the outer container that
encloses the signed data. The signed content is placed inside a
<ds:Object> element, which is a child of the
<Signature> element.
The <Reference> element inside the
<SignedInfo> references the ID of the
<ds:Object> containing the payload. Unlike enveloped
signatures, no specialized exclusion transforms are needed because the
signature metadata sits outside the signed payload.
Structural Example
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:Reference URI="#payload1">
<!-- Digest and algorithms -->
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:Object Id="payload1">
<OriginalData>This entire payload is inside the signature</OriginalData>
</ds:Object>
</ds:Signature>Detached Signatures
In a detached signature, the <Signature> element
and the signed data are completely independent of each other. They do
not have a parent-child relationship.
Detached signatures occur in two common variations:
- Internal Detached: The signature and the signed data exist within the same XML document as sibling elements under a common root.
- External Detached: The signature and the signed data exist in completely separate files or locations. The signed data can be an external XML file, an image, a PDF, or any binary resource accessed via a URI.
Structural Example (Internal Detached)
<Container>
<DataElement id="data1">Data signed independently</DataElement>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:Reference URI="#data1">
<!-- Digest and algorithms -->
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
</ds:Signature>
</Container>Structural Example (External Detached)
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:Reference URI="https://example.com/documents/contract.pdf">
<!-- Digest and algorithms -->
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
</ds:Signature>Structural Comparison Summary
| Signature Type | Signature Position | Signed Data Position | Reference Target |
|---|---|---|---|
| Enveloped | Child element | Parent/Ancestor element | Root or parent node ID |
| Enveloping | Root/Container | Inside <ds:Object>
child |
<ds:Object> ID |
| Detached | Separate node or file | Sibling node or external resource | Node ID or External URI |