Copyright © 2002 W3C® (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
This document specifies an XML Signature "decryption transform" that enables XML Signature applications to distinguish between those XML Encryption structures that were encrypted before signing (and must not be decrypted) and those that were encrypted after signing (and must be decrypted) for the signature to validate.
This is an editors' draft with no standing.
This specification from the XML Encryption Working Group (Activity) is a Candidate Recommendation of the W3C. None of the last call issues on the XML Encryption specifications concerned this specification. Furthermore, the WG considers this specification to be stable and invites implementation feedback during this period.
The exit criteria for this phase is at least two interoperable implementations of this transform with acceptable performance. The interoperability of this specification will be demonstrated as an algorithm in the XML Encryption Syntax and Processing Interoperability Report. We expect to meet all requirements of that report within the two month Candidate Recommendation period (closing April 25). Specific areas where we would appreciate further experience are:
Publication of this document does not imply endorsement by the W3C membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite a W3C Working Draft as anything other than a "work in progress." A list of current W3C working drafts can be found at http://www.w3.org/TR/.
Please send comments to the editors (<merlin@baltimore.ie>, <imamu@jp.ibm.com>, and <maruyama@jp.ibm.com>) and cc: the list xml-encryption@w3.org (publicly archived).
Patent disclosures relevant to this specification may be found on the Working Group's patent disclosure page in conformance with W3C policy.
It has been noted by David Solo in [Solo] that both signature [XML-Signature] and encryption [XML-Encryption] operations may be performed on an XML document at any time and in any order, especially in scenarios such as workflow. For example, Alice wishes to order and pay for a book from Bob using the mutually trusted payment system ZipPay. Bob creates an order form including the book title, price and his account info. He wants to sign all of this information, but will subsequently encrypt his account info for ZipPay only. He sends this to Alice who affirms the book title and price, signs the form and presents the twice-signed order with her own payment information to ZipPay. To validate both signatures ZipPay will have to know that the cipher data version of the encrypted information is necessary for validating Alice's signature, but the plain data form is necessary for validating Bob's signature. (See "Sign What You See" (section 5.2) for more on signing encrypted data.)
Since encryption operations applied to part of the signed content after a signature operation cause a signature not to be verifiable, it is necessary to decrypt the portions encrypted after signing before the signature is verified. The "decryption transform" proposed in this document provides a mechanism; decrypting only signed-then-encrypted portions (and ignoring encrypted-then-signed ones). A signer can insert this transform in a transform sequence (e.g., before Canonical XML [XML-C14N] or XPath [XPath]) if there is a possibility that someone will encrypt portions of the signature.
The transform defined in this document is intended to propose a resolution to the
decryption/verification ordering issue within signed resources. It is out of
scope of this document to deal with the cases where the ordering can be derived
from the context. For example, when a ds:DigestValue
element or a
(part of) ds:SignedInfo
element is encrypted, the ordering is
obvious (without decryption, signature verification is not possible) and there is
no need to introduce a new transform.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [Keywords].
This document makes use of the XML Encryption [XML-Encryption] and XML Signature [XML-Signature] namespaces, and defines it own, with the following prefixes:
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:dcrpt="http://www.w3.org/2001/04/decrypt#"
While implementations MUST support XML and XML namespaces, the
use of our "xenc
", "ds
", and
"dcrpt
" XML namespace prefixes is OPTIONAL; we use
this facility to provide compact and readable exposition.
The contributions of the following Working Group members to this specification are gratefully acknowledged:
This transform requires an XPath node-set [XPath] for input. If an octet stream is given
as input, it MUST be converted to a node-set as described in
The
Reference Processing Model (section 4.3.3.2) of the XML
Signature specification [XML-Signature]. The transform decrypts
all the xenc:EncryptedData
elements except for
those specified by dcrpt:Except
elements. dcrpt:Except
is defined below via XML
Schema [XML-Schema] and appears as
direct child elements of the ds:Transform
element. The output of the transform is a node-set.
The REQUIRED URI
attribute value of the
dcrpt:Except
element MUST be a non-empty
same-document URI reference [URI] (i.e., a
number sign ('#') character followed by an XPointer expression
[XPointer] (as profiled by The
Reference Processing Model (section 4.3.3.2) of the XML
Signature specification [XML-Signature])) and identify
xenc:EncryptedData
elements within the input to the
transform.
Schema Definition: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" [ <!ATTLIST schema xmlns:dt CDATA #FIXED "http://www.w3.org/2001/04/decrypt#"> <!ENTITY % p ''> <!ENTITY % s ''> ]> <schema xmlns="http://www.w3.org/2001/XMLSchema" version="0.1" xmlns:dt="http://www.w3.org/2001/04/decrypt#" targetNamespace="http://www.w3.org/2001/04/decrypt#" elementFormDefault="qualified"> <element name="Except" type="dt:ExceptType"/> <complexType name="ExceptType"> <attribute name="Id" type="ID" use="optional"/> <attribute name="URI" type="anyURI" use="required"/> </complexType> </schema>
This section describes the processing rules of the transform. The rules are written as two functions; the inputs and outputs of the transform are those of the foo() function, which itself calls the bar() function.
where N is a node-set and E is a set of
exception URIs held by URI
attributes of
dcrpt:Except
elements. O is a
node-set, computed as follows:
xenc:EncryptedData
element
d and its descendants, if Od
from Y is a node-set, convert it
to an octet stream, and if it is already an octet stream,
just emit it as is. Let C be the resulting octet
stream.
xmlns=""
MUST be
emitted with every apex element that has no namespace
prefix and URI as described in Serializing
XML (section 4.3.3) of the XML Encryption
specification [XML-Encryption].
xenc:EncryptedData
element causing a
parsing error.
xenc:EncryptedData
elements, then
N is still canonicalized and parsed.
where N is a node-set and X is a set of location-sets. Y is a set of node-sets and/or octet streams, computed as follows:
xenc:EncryptedData
that are not identified
by any location-set in X.
xenc:EncryptedData
element, only
location-sets in X resulting
from exception URIs with a full XPointer
"xpointer(id('ID'))" or bare name [XPointer] are considered.
xenc:EncryptedData
element
d from D:
Type
attribute, resulting in a node-set or octet stream
Od.
xenc:EncryptedData
element with the
Type
attribute whose value is &xenc;Element
or &xenc;Content
is specified in A
Decrypt Implementation (section 4.3.1) of the
XML Encryption specification [XML-Encryption], and the
result is a node-set.
Type
attribute is absent or its
value is neither &xenc;Element
nor &xenc;Content,
the result is an octet stream in default. However, the
implementation MAY process it further in accordance
with its type, if any, resulting in a node-set.
xenc:EncryptedData
element fails, then the implementation MAY signal a
failure of the transform. Alternatively, it MAY also
skip such xenc:EncryptedData
element and
continue processing.
xenc:EncryptedData
element being
decrypted, then this SHOULD correspond to an encrypted single-rooted
node-set. However, this need not be the case: after
decryption, multiple top-level nodes may be well-formed if
they consist of whitespace, comments, processing instructions
and a single element. No special processing is required to
test for this condition because ill-formed data will result in
a parsing error.
xenc:EncryptedData
element uses same-document
references, or if an exceptional super-encrypted
xenc:EncryptedData
element is referenced by a URI
with an XPointer except a full XPointer "xpointer(id('ID'))"
and bare name.
Super-encryption of signed data when these conditions are met
is NOT RECOMMENDED. On the contrary, if there is a possibility
that super-encryption will be
performed, their use is NOT RECOMMENDED. However, applications
may solve some of these super-encryption problems through the
use of encryption properties that identify exceptional
super-encrypted elements, how same-document references from
the encrypted data should be resolved, and to which signature
such encryption properties apply. However, details of such a
solution are beyond the scope of this specification.
#xpointer(/ToBeSigned/*[3])
will no longer
function if the first two children of the
ToBeSigned
element are encrypted together. Care
SHOULD be taken when employing such references in association
with the decryption transform.
xenc:EncryptedKey
elements within its scope of specifically indicating elements,
and their exceptions, that should be decrypted. An
xenc:EncryptedKey
element that exists as a
descendent of xenc:EncryptedData
element might be
decrypted and will be removed from the original document as
part of processing its ancestor
xenc:EncryptedData
element with the
transform. However, a lone xenc:EncryptedKey
element will be processed like any other data: a signature is
presumed to be over that actual element and not its decrypted
form. Consequently, we RECOMMEND that
xenc:EncryptedKey
elements always be children of
an xenc:EncryptedData
element's
ds:KeyInfo
element when they fall within the
scope of a signature.
It is out of scope of this document how to create a ds:Transform
element and where to insert it in a transform sequence. In this section, we just
show a way to create the element as an advisory.
A ds:Transform
element can be created by the following steps:
xenc:EncryptedData
, create an dcrpt:Except
element
referencing the node.
ds:Transform
element, including the algorithm identifier
of this transform and all the dcrpt:Except
elements created in
Step 3.
Suppose that a part of the following XML document
([02-14]
) is to be signed. Note that a few parts of
the document ([05,11,12]
) are already encrypted
prior to signature. Also suppose that the signer anticipates
that additional parts of the document will be encrypted after
signing.
[01] <Document> [02] <ToBeSigned Id="tbs"> [03] <Part number="1"> [04] <Data>...</Data> [05] <xenc:EncryptedData Id="#secret-1" .../> [06] </Part> [07] <Part number="2"> [08] <Data>...</Data> [09] </Part> [10] <Secrets> [11] <xenc:EncryptedData .../> [12] <xenc:EncryptedData .../> [13] </Secrets> [14] </ToBeSigned> [15] </Document>
In order to let the recipient know the proper order of
decryption and signature verification, the signer includes the
decryption transform ([19-22]
) in the
signature. The dcrpt:Except
elements
([20,21]
) identify parts of the document that are
already encrypted.
[01] <Document> [02] <ToBeSigned Id="tbs"> [03] <Part number="1"> [04] <Data>...</Data> [05] <xenc:EncryptedData Id="#secret-1" .../> [06] </Part> [07] <Part number="2"> [08] <Data>...</Data> [09] </Part> [10] <Secrets> [11] <xenc:EncryptedData .../> [12] <xenc:EncryptedData .../> [13] </Secrets> [14] </ToBeSigned> [15] <dsig:Signature ...> [16] ... [17] <dsig:Reference URI="#tbs"> [18] <dsig:Transforms> [19] <dsig:Transform Algorithm="http://www.w3.org/2001/04/decrypt#"> [20] <dcrpt:Except URI="#secret-1"/> [21] <dcrpt:Except URI="#xpointer(id('tbs')/Secrets/*)"/> [22] </dsig:Transform> [23] </dsig:Transforms> [24] ... [25] </dsig:Reference> [26] ... [27] </dsig:Signature> [28] </Document>
Consider that this document is subsequently encrypted by various processes, resulting in the following:
[01] <Document> [02] <ToBeSigned Id="tbs"> [03] <xenc:EncryptedData Id="part-1" Type="&enc;Element" .../> [04] <xenc:EncryptedData Id="part-2" Type="&enc;Element" .../> [05] <Secrets> [06] <xenc:EncryptedData .../> [07] <xenc:EncryptedData .../> [08] </Secrets> [09] </ToBeSigned> [10] <dsig:Signature ...> [11] ... [12] <dsig:Reference URI="#tbs"> [13] <dsig:Transforms> [14] <dsig:Transform Algorithm="http://www.w3.org/2001/04/decrypt#"> [15] <dcrpt:Except URI="#secret-1"/> [16] <dcrpt:Except URI="#xpointer(id('tbs')/Secrets/*)"/> [17] </dsig:Transform> [18] </dsig:Transforms> [19] ... [20] </dsig:Reference> [21] ... [22] </dsig:Signature> [23] </Document>
Execution of the decryption transform will proceed as follows:
ToBeSigned
element and its
children, less comments ([02-09]
). The parameter
to the transform, E, is a set containing the two
exception URIs ([15,16]
).
Secrets
element ([06,07]
); this is
the exception location-set in X.
xenc:EncryptedData
elements, dpart-1 ([03]
) and
dpart-2 ([04]
). Each of these
is decrypted, resulting in the following node-sets for
Opart-1 and Opart-2:
[01] <Part number="1"> [02] <Data>...</Data> [03] <xenc:EncryptedData Id="#secret-1" .../> [04] </Part>
[01] <Part number="2"> [02] <xenc:EncryptedData Id="#data-2" Type="&enc;Element" .../> [03] </Part>
Note that part of the second node-set ([02]
) has
been super-encrypted.
xenc:EncryptedData
elements
([03]
and [02]
) have been
revealed. However, the first matches an exception URI with a
bare name and so is not considered further; hence, D
for Opart-1 is empty while D for
Opart-2 contains just the
xenc:EncryptedData
element
ddata-2 ([02]
). This is
decrypted again, resulting in the following node-set
Odata-2:
[01] <Data>...</Data>
xenc:EncryptedData
element are revealed,
so D for Odata-2 is empty and
processing falls through to canonicalization.
xenc:EncryptedData
elements that were decrypted,
it canonicalizes the replacement node-sets. Similarly, it also
replaces any decrypted xenc:EncryptedData
elements in the replacement node-sets. Further,
canonicalization of any replacement node-sets is augmented
such that xmlns=""
is emitted on any apex
elements that have no namespace prefix and URI. The resulting
canonicalized data are the following:
[01] <Document> [02] <ToBeSigned Id="tbs"> [03] <Part xmlns="" number="1"> [04] <Data>...</Data> [05] <xenc:EncryptedData Id="#secret-1" .../> [06] </Part> [07] <Part xmlns="" number="2"> [08] <Data xmlns="">...</Data> [09] </Part> [10] <Secrets> [11] <xenc:EncryptedData .../> [12] <xenc:EncryptedData .../> [13] </Secrets> [14] </ToBeSigned> [15] </Document>
When this algorithm is used to facilitate subsequent encryption of data already
signed, the digest value of the signed resource still appears in clear text in a
ds:Reference
element. As noted by Hal Finney in [Finney], such a signature may reveal information (via the
digest value) over encrypted data that increases the encryption's vulnerability
to plain-text-guessing attacks. This consideration is out of scope of this
document and (if relevant) should be addressed by applications. For example, as
proposed by Amir Herzberg in [Herzberg], one may include
a random 'salt' in a resource being signed to increase its entropy.
Another approach is that when a signature referent is encrypted, one may also
encrypt the signature (or at least the ds:DigestValue
elements). As
noted by Joseph Reagle in [Reagle], this latter solution
works only if signature and encryption are well known by each other. For example,
the signature may not be known of because it is detached. Or, it may be already
encrypted! Consider, Alice Encrypts element A and the Signature over the parent
of A. Bob Encrypts element B (sibling of A) but not the Signature since he
doesn't know about it. Alice then decrypts A and it's Signature, which may
provide information to a subsequent plain text attack on the encrypted B.
This specification serves scenarios in which a person might sign encrypted data. Because XML Signature [XML-Signature] has only a simple semantic whereby a key is associated with some data -- and nothing more -- the signing of encrypted data is a legitimate process. For example, someone might run a content-neutral time stamp service that will sign any data sent to it with its time-stamping key under the semantic, "I received this on $date $time." However, applications often explicitly or implicitly associate more substantive semantics (e.g., authorizes, agrees, authors) with a signature. No one should be asked to apply a signature and its semantic to data he or she did not see. Just as the principles of Only What is 'Seen' Should be Signed and 'See' What is Signed are important for understanding the import of an XML Signature, they are doubly important when semantics are associated with that signature: one MUST NOT infer that a signature over encrypted data is also a signature over its plain text form, nor that the meaning of that signature over the encrypted data also applies to the plain text. If one wishes to sign the plain text form of data which is later encrypted, use the transform specified in this document!