W3C
Candidate
Recommendation
Snapshot
06
Copyright © 2025 World Wide Web Consortium . W3C ® liability , trademark and permissive document license rules apply.
This specification describes mechanisms for ensuring the authenticity and integrity of verifiable credentials and similar types of constrained digital documents using cryptography, especially through the use of digital signatures and related mathematical proofs.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
The Working Group is actively seeking implementation feedback for this specification. In order to exit the Candidate Recommendation phase, the Working Group has set the requirement of at least two independent implementations for each mandatory feature in the specification. For details on the conformance testing process, see the test suites listed in the implementation report .
Any feature with less than two independent implementations in the Data Integrity portions of each cryptosuite implementation report is an "at risk" feature and might be removed before the transition to W3C Proposed Recommendation.
This document was published by the Verifiable Credentials Working Group as a Candidate Recommendation Snapshot using the Recommendation track .
Publication as a Candidate Recommendation does not imply endorsement by W3C and its Members. A Candidate Recommendation Snapshot has received wide review , is intended to gather implementation experience , and has commitments from Working Group members to royalty-free licensing for implementations.
This Candidate Recommendation is not expected to advance to Proposed Recommendation any earlier than 19 January 2024.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This document is governed by the 03 November 2023 W3C Process Document .
This section is non-normative.
This specification describes mechanisms for ensuring the authenticity and integrity of verifiable credentials and similar types of constrained digital documents using cryptography, especially through the use of digital signatures and related mathematical proofs. Cryptographic proofs enable functionality that is useful to implementors of distributed systems. For example, proofs can be used to:
This section is non-normative.
The operation of Data Integrity is conceptually simple. To create a cryptographic proof, the following steps are performed: 1) Transformation, 2) Hashing, and 3) Proof Generation.
Transformation is a process described by a transformation algorithm that takes input data and prepares it for the hashing process. One example of a possible transformation is to take a record of people's names that attended a meeting, sort the list alphabetically by the individual's family name, and rewrite the names on a piece of paper, one per line, in sorted order. Examples of transformations include canonicalization and binary-to-text encoding.
Hashing is a process described by a hashing algorithm that calculates an identifier for the transformed data using a cryptographic hash function . This process is conceptually similar to how a phone address book functions, where one takes a person's name (the input data) and maps that name to that individual's phone number (the hash). Examples of cryptographic hash functions include SHA-3 and BLAKE-3 .
Proof Generation is a process described by a proof serialization algorithm that calculates a value that protects the integrity of the input data from modification or otherwise proves a certain desired threshold of trust. This process is conceptually similar to the way a wax seal can be used on an envelope containing a letter to establish trust in the sender and show that the letter has not been tampered with in transit. Examples of proof serialization functions include digital signatures , proofs of stake , and proofs of knowledge , in general.
To verify a cryptographic proof, the following steps are performed: 1) Transformation, 2) Hashing, and 3) Proof Verification.
During verification, the transformation and hashing steps are conceptually the same as described above.
Proof Verification is a process that is described by a proof verification algorithm that applies a cryptographic proof verification function to see if the input data can be trusted. Possible proof verification functions include digital signatures , proofs of stake , and proofs of knowledge , in general.
This specification details how cryptographic software architects and implementers can package these processes together into things called cryptographic suites and provide them to application developers for the purposes of protecting the integrity of application data in transit and at rest.
This section is non-normative.
This specification optimizes for the following design goals:
While this specification primarily focuses on verifiable credentials , the design of this technology is generalized, such that it can be used for other use cases. In these instances, implementers are expected to perform their own due diligence and expert review as to the applicability of the technology to their use case.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY , MUST , MUST NOT , OPTIONAL , and SHOULD in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.
A conforming secured document is any byte sequence that can be converted to a JSON document that follows the relevant normative requirements in Sections 2.1 Proofs , 2.2 Proof Purposes , 2.3 Resource Integrity , 2.4 Contexts and Vocabularies , and 3.1 DataIntegrityProof .
A conforming cryptographic suite specification is any specification that follows the relevant normative requirements in Section 3. Cryptographic Suites .
A conforming processor is any algorithm realized as software and/or hardware that generates and/or consumes a conforming secured document according to the relevant normative statements in Section 4. Algorithms . Conforming processors MUST produce errors when non-conforming documents are consumed.
This section defines the terms used in this specification. A link to these terms is included whenever they appear in this specification.
A set of parameters that can be used together with a process to independently verify a proof. For example, a cryptographic public key can be used as a verification method with respect to a digital signature; in such usage, it verifies that the signer possessed the associated cryptographic secret key .
"Verification" and "proof" in this definition are intended to apply broadly. For example, a cryptographic public key might be used during Diffie-Hellman key exchange to negotiate a shared symmetric key for encryption. This guarantees the integrity of the key agreement process. It is thus another type of verification method, even though descriptions of the process might not use the words "verification" or "proof."
This section specifies the data model that is used for expressing data integrity proofs and the integrity of related resources.
All
of
the
data
model
properties
and
types
in
this
specification
map
to
URLs.
The
vocabulary
where
these
URLs
are
defined
is
the
The
Security
Vocabulary
.
The
explicit
mechanism
that
is
used
to
perform
this
mapping
in
a
secured
document
is
the
@context
property.
The
mapping
mechanism
is
defined
by
JSON-LD
1.1
.
To
ensure
a
document
can
be
interoperably
consumed
without
the
use
of
a
JSON-LD
library,
document
authors
are
advised
to
ensure
that
domain
experts
have
1)
specified
the
expected
order
for
all
values
associated
with
a
@context
property,
2)
published
cryptographic
hashes
for
each
@context
file,
and
3)
deemed
that
the
contents
of
each
@context
file
are
appropriate
for
the
intended
use
case.
When
a
document
is
processed
by
a
processor
that
does
not
utilize
JSON-LD
libraries,
and
there
is
a
requirement
to
use
the
same
semantics
as
those
used
in
a
JSON-LD
environment,
implementers
are
advised
to
1)
enforce
the
expected
order
and
values
in
the
@context
property,
and
2)
ensure
that
each
@context
file
matches
the
known
cryptographic
hashes
for
each
@context
file.
Using
static,
versioned,
@context
files
with
published
cryptographic
hashes
in
conjunction
with
JSON
Schema
is
one
acceptable
approach
to
implementing
the
mechanisms
described
above,
which
ensures
proper
term
identification,
typing,
and
order,
when
a
processor
that
does
not
utilize
a
JSON-LD
library
is
used.
See
the
section
on
Type-Specific
Processing
in
Verifiable
Credentials
Data
Model
v2.0
for
more
details.
A data integrity proof provides information about the proof mechanism, parameters required to verify that proof, and the proof value itself. All of this information is provided using Linked Data vocabularies such as The Security Vocabulary .
When
expressing
a
data
integrity
proof
on
an
object,
a
proof
property
MUST
be
used.
The
proof
property
within
a
verifiable
credential
is
a
named
graph
.
If
present,
its
value
MUST
be
either
a
single
object,
or
an
unordered
set
of
objects,
expressed
using
the
properties
below:
urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5
).
The
usage
of
this
property
is
further
explained
in
Section
2.1.2
Proof
Chains
.
DataIntegrityProof
and
Ed25519Signature2020
.
Proof
types
determine
what
other
fields
are
required
to
secure
and
verify
the
proof.
assertionMethod
)
during
a
login
process
(
authentication
)
which
would
then
result
in
the
creation
of
a
verifiable
credential
they
never
meant
to
create
instead
of
the
intended
action,
which
was
to
merely
log
in
to
a
website.
verificationMethod
is
OPTIONAL
,
but
if
it
is
not
included,
other
properties
such
as
cryptosuite
might
provide
a
mechanism
by
which
to
obtain
the
information
necessary
to
verify
the
proof.
Note
that
when
verificationMethod
is
expressed
in
a
data
integrity
proof
,
the
value
points
to
the
actual
location
of
the
data;
that
is,
the
verificationMethod
references,
via
a
URL,
the
location
of
the
public
key
that
can
be
used
to
verify
the
proof.
This
public
key
data
is
stored
in
a
controller
document
,
which
contains
a
full
description
of
the
verification
method.
type
is
DataIntegrityProof
,
cryptosuite
MUST
be
specified;
otherwise,
cryptosuite
MAY
be
specified.
If
specified,
its
value
MUST
be
a
string.
dateTimeStamp
string,
either
in
Universal
Coordinated
Time
(UTC),
denoted
by
a
Z
at
the
end
of
the
value,
or
with
a
time
zone
offset
relative
to
UTC.
A
conforming
processor
MAY
chose
to
consume
time
values
that
were
incorrectly
serialized
without
an
offset.
Incorrectly
serialized
time
values
without
an
offset
are
to
be
interpreted
as
UTC.
expires
property
is
OPTIONAL
and,
if
present,
specifies
when
the
proof
expires.
If
present,
it
MUST
be
an
[
XMLSCHEMA11-2
]
dateTimeStamp
string,
either
in
Universal
Coordinated
Time
(UTC),
denoted
by
a
Z
at
the
end
of
the
value,
or
with
a
time
zone
offset
relative
to
UTC.
A
conforming
processor
MAY
chose
to
consume
time
values
that
were
incorrectly
serialized
without
an
offset.
Incorrectly
serialized
time
values
without
an
offset
are
to
be
interpreted
as
UTC.
domain
property
is
OPTIONAL
.
It
conveys
one
or
more
security
domains
in
which
the
proof
is
meant
to
be
used.
If
specified,
the
associated
value
MUST
be
either
a
string,
or
an
unordered
set
of
strings.
A
verifier
SHOULD
use
the
value
to
ensure
that
the
proof
was
intended
to
be
used
in
the
security
domain
in
which
the
verifier
is
operating.
The
specification
of
the
domain
parameter
is
useful
in
challenge-response
protocols
where
the
verifier
is
operating
from
within
a
security
domain
known
to
the
creator
of
the
proof.
Example
domain
values
include:
domain.example
(DNS
domain),
https://domain.example:8443
(Web
origin),
mycorp-intranet
(bespoke
text
string),
and
b31d37d4-dd59-47d3-9dd8-c973da43b63a
(UUID).
domain
is
specified.
The
value
is
used
once
for
a
particular
domain
and
window
of
time.
This
value
is
used
to
mitigate
replay
attacks.
Examples
of
a
challenge
value
include:
1235abcd6789
,
79d34551-ae81-44ae-823b-6dadbab9ebd4
,
and
ruby
.
verificationMethod
specified.
The
value
MUST
use
a
header
and
encoding
as
described
in
Section
2.4
Multibase
of
the
Controlled
previousProof
property
is
OPTIONAL
.
If
present,
it
MUST
be
a
string
value
or
an
unordered
list
of
string
values.
Each
value
identifies
another
data
integrity
proof
,
all
of
which
MUST
also
verify
for
the
current
proof
to
be
considered
verified.
This
property
is
used
in
Section
2.1.2
Proof
Chains
.
A proof can be added to a JSON document like the following:
{ "myWebsite": "https://hello.world.example/" };
The
following
proof
secures
the
document
above
using
the
eddsa-jcs-2022
cryptography
suite
[
DI-EDDSA
],
which
produces
a
verifiable
digital
proof
by
transforming
the
input
data
using
the
JSON
Canonicalization
Scheme
(JCS)
[
RFC8785
]
and
then
digitally
signing
it
using
an
Edwards
Digital
Signature
Algorithm
(EdDSA).
{ "myWebsite": "https://hello.world.example/", "proof": { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "created": "2023-03-05T19:23:24Z", "verificationMethod": "https://di.example/issuer#z6MkjLrk3gKS2nnkeWcmcxiZPGskmesDpuwRBorgHxUXfxnG", "proofPurpose": "assertionMethod", "proofValue": "zQeVbY4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYV 8nQApmEcqaqA3Q1gVHMrXFkXJeV6doDwLWx" } }
Similarly, a proof can be added to a JSON-LD data document like the following:
{ "@context": {"myWebsite": "https://vocabulary.example/myWebsite"}, "myWebsite": "https://hello.world.example/" };
The
following
proof
secures
the
document
above
by
using
the
ecdsa-rdfc-2019
cryptography
suite
[
DI-ECDSA
],
which
produces
a
verifiable
digital
proof
by
transforming
the
input
data
using
the
RDF
Dataset
Canonicalization
Scheme
[
RDF-CANON
]
and
then
digitally
signing
it
using
the
Elliptic
Curve
Digital
Signature
Algorithm
(ECDSA).
{ "@context": [ {"myWebsite": "https://vocabulary.example/myWebsite"}, "https://w3id.org/security/data-integrity/v2" ], "myWebsite": "https://hello.world.example/", "proof": { "type": "DataIntegrityProof", "cryptosuite": "ecdsa-rdfc-2019", "created": "2020-06-11T19:14:04Z", "verificationMethod": "https://ldi.example/issuer#zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP", "proofPurpose": "assertionMethod", "proofValue": "zXb23ZkdakfJNUhiTEdwyE598X7RLrkjnXEADLQZ7vZyUGXX8cyJZR BkNw813SGsJHWrcpo4Y8hRJ7adYn35Eetq" } }
This
specification
enables
the
expression
of
dates
and
times,
such
as
through
the
created
and
expires
properties.
This
information
might
be
indirectly
exposed
to
an
individual
if
a
proof
is
processed
and
is
detected
to
be
outside
an
allowable
time
range.
When
displaying
date
and
time
values
related
to
the
validity
of
cryptographic
proofs,
implementers
are
advised
to
respect
the
locale
and
local
calendar
preferences
of
the
individual
[
LTLI
].
Conversion
of
timestamps
to
local
time
values
are
expected
to
consider
the
time
zone
expectations
of
the
individual.
See
Verifiable
Credentials
Data
Model
v2.0
for
more
details
about
representing
time
values
to
individuals.
{ "@context": [ {"myWebsite": "https://vocabulary.example/myWebsite"}, "https://w3id.org/security/data-integrity/v2" ], "myWebsite": "https://hello.world.example/", "proof": { "type": "DataIntegrityProof", "cryptosuite": "ecdsa-rdfc-2019", "created": "2020-06-11T19:14:04Z", // the proof expires a month after it was created "expires": "2020-07-11T19:14:04Z", "verificationMethod": "https://ldi.example/issuer#zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP", "proofPurpose": "assertionMethod", "proofValue": "z98X7RLrkjnXEADJNUhiTEdwyE5GXX8cyJZRLQZ7vZyUXb23Zkdakf RJ7adYY8hn35EetqBkNw813SGsJHWrcpo4" } }
The Data Integrity specification supports the concept of multiple proofs in a single document. There are two types of multi-proof approaches that are identified: Proof Sets (un-ordered) and Proof Chains (ordered).
A
proof
set
is
useful
when
the
same
data
needs
to
be
secured
by
multiple
entities,
but
where
the
order
of
proofs
does
not
matter,
such
as
in
the
case
of
a
set
of
signatures
on
a
contract.
A
proof
set,
which
has
no
order,
is
represented
by
associating
a
set
of
proofs
with
the
proof
key
in
a
document.
{
"@context": [
{"myWebsite": "https://vocabulary.example/myWebsite"},
"https://w3id.org/security/data-integrity/v2"
],
"myWebsite": "https://hello.world.example/",
"proof": [{
// This is one of the proofs in the set
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"created": "2020-11-05T19:23:24Z",
"verificationMethod": "https://ldi.example/issuer/1#z6MkjLrk3gKS2nnkeW cmcxiZPGskmesDpuwRBorgHxUXfxnG",
"proofPurpose": "assertionMethod",
"proofValue": "z4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYVQeVbY8 nQAVHMrXFkXJpmEcqdoDwLWxaqA3Q1geV6"
}, {
// This is the other proof in the set
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"created": "2020-11-05T13:08:49Z",
"verificationMethod": "https://pfps.example/issuer/2#z6MkGskxnGjLrk3gK S2mesDpuwRBokeWcmrgHxUXfnncxiZP",
"proofPurpose": "assertionMethod",
"proofValue": "z5QLBrp19KiWXerb8ByPnAZ9wujVFN8PDsxxXeMoyvDqhZ6Qnzr5CG9 876zNht8BpStWi8H2Mi7XCY3inbLrZrm95"
}]
}
A
proof
chain
is
useful
when
the
same
data
needs
to
be
signed
by
multiple
entities
and
the
order
of
when
the
proofs
occurred
matters,
such
as
in
the
case
of
a
notary
counter-signing
a
proof
that
had
been
created
on
a
document.
A
proof
chain,
where
proof
order
needs
to
be
preserved,
is
expressed
by
providing
at
least
one
proof
with
an
id
,
such
as
a
UUID
[
RFC9562
],
and
another
proof
with
a
previousProof
value
that
identifies
the
previous
proof.
{
"@context": [
{"myWebsite": "https://vocabulary.example/myWebsite"},
"https://w3id.org/security/data-integrity/v2"
],
"myWebsite": "https://hello.world.example/",
"proof": [{
// The 'id' value identifies this specific proof
"id": "urn:uuid:60102d04-b51e-11ed-acfe-2fcd717666a7",
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"created": "2020-11-05T19:23:42Z",
"verificationMethod": "https://ldi.example/issuer/1#z6MkjLrk3gKS2nnke WcmcxiZPGskmesDpuwRBorgHxUXfxnG",
"proofPurpose": "assertionMethod",
"proofValue": "zVbY8nQAVHMrXFkXJpmEcqdoDwLWxaqA3Q1geV64oey5q2M3XKaxup 3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYVQe"
}, {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"created": "2020-11-05T21:28:14Z",
"verificationMethod": "https://pfps.example/issuer/2#z6MkGskxnGjLrk3g KS2mesDpuwRBokeWcmrgHxUXfnncxiZP",
"proofPurpose": "assertionMethod",
"proofValue": "z6Qnzr5CG9876zNht8BpStWi8H2Mi7XCY3inbLrZrm955QLBrp19Ki WXerb8ByPnAZ9wujVFN8PDsxxXeMoyvDqhZ",
// The 'previousProof' value identifies which proof is verified before this one
"previousProof": "urn:uuid:60102d04-b51e-11ed-acfe-2fcd717666a7"
}]
}
When securing data in a document, it is important to clearly delineate the data being protected, which is every graph expressed in the document except the one containing the data associated with a securing mechanism, which is called a proof graph . Creating this separation enables the processing algorithms to deterministically protect and verify a secured document.
The
information
contained
in
an
input
document
before
a
data
integrity
proof
is
added
to
the
document
is
expressed
in
one
or
more
graphs.
To
ensure
that
information
from
different
data
integrity
proofs
is
not
accidentally
co-mingled,
the
concept
of
a
proof
graph
is
used
to
encapsulate
each
data
integrity
proof
.
Each
value
associated
with
the
proof
property
of
the
document
identifies
a
separate
graph,
which
is
sometimes
referred
to
as
a
named
graph
,
of
type
ProofGraph
,
which
contains
a
single
data
integrity
proof
.
Using
these
graphs
has
a
concrete
effect
when
performing
JSON-LD
processing,
as
this
properly
separates
statements
expressed
in
one
graph
from
those
in
another
graph.
Implementers
that
limit
their
processing
to
other
media
types,
such
as
JSON,
YAML,
or
CBOR,
will
need
to
keep
this
in
mind
if
they
merge
data
from
one
document
with
data
from
another,
such
as
when
an
id
value
string
is
the
same
in
both
documents.
It
is
important
to
not
merge
objects
that
seem
to
have
similar
properties,
when
those
objects
do
not
have
an
id
property
and/or
use
a
global
identifier
type
such
as
a
URL,
as
without
these,
is
not
possible
to
tell
whether
two
such
objects
are
expressing
information
about
the
same
entity.
A proof that describes its purpose helps prevent it from being misused for some other purpose. Proof purposes enable verifiers to know the intent of the creator of a proof so a message cannot be accidentally abused for another purpose. For example, a message signed for the purpose of merely making an assertion (perhaps intended to be widely shared) being abused as a message to authenticate to a service or take some action (such as invoking a capability to do something).
It
is
important
to
note
that
proof
purposes
are
a
different
mechanism
from
the
key_ops
restrictions
in
JSON
Web
Key
(JWK)
,
the
KeyUsage
restriction
in
the
Web
Cryptography
API
and
the
Internet
X.509
Public
Key
Infrastructure
Certificate
and
Certificate
Revocation
List
(CRL)
Profile
.
Proof
purposes
are
expressions
on
why
a
proof
was
created
and
its
intended
domain
of
usage
whereas
the
other
mechanisms
mentioned
are
intended
to
limit
what
a
private
key
can
be
used
to
do.
A
proof
purpose
"travels"
with
the
proof
while
a
key
restriction
does
not.
The following is a list of commonly used proof purpose values.
When a link to an external resource is included in a conforming secured document , it is desirable to know whether the resource that is identified has changed since the proof was created. This applies to cases where there is an external resource that is remotely retrieved as well as to cases where the verifier might have a locally cached copy of the resource.
To
enable
confirmation
that
a
resource
referenced
by
a
conforming
secured
document
has
not
changed
since
the
document
was
secured,
an
implementer
MAY
include
a
property
named
digestMultibase
in
any
object
that
includes
an
id
property.
If
present,
the
digestMultibase
value
MUST
be
a
single
string
value,
or
an
list
of
string
values,
each
of
which
is
a
Multibase
-encoded
Multihash
value.
JSON-LD
context
authors
are
expected
to
add
digestMultibase
to
contexts
that
will
be
used
in
documents
that
refer
to
other
resources
and
to
include
an
associated
cryptographic
digest.
For
example,
the
Verifiable
Credentials
Data
Model
v2.0
base
context
(
https://www.w3.org/ns/credentials/v2
)
includes
the
digestMultibase
property.
An example of a resource integrity protected object is shown below:
{
...
"image": {
"id": "https://university.example.org/images/58473",
"digestMultibase": "zQmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"
},
...
}
Implementers are urged to consult appropriate sources, such as the FIPS 180-4 Secure Hash Standard and the Commercial National Security Algorithm Suite 2.0 to ensure that they are choosing a hash algorithm that is appropriate for their use case.
This section lists cryptographic hash values that might change during the Candidate Recommendation phase based on implementer feedback that requires the referenced files to be modified.
Implementations that perform JSON-LD processing MUST treat the following JSON-LD context URLs as already resolved, where the resolved document matches the corresponding hash values below:
Context URL and Hash |
---|
URL:
https://w3id.org/security/data-integrity/v2
SHA2-256 Digest:
67f21e6e33a6c14e5ccfd2fc7865f7474fb71a04af7e94136cb399dfac8ae8f4
|
URL:
https://w3id.org/security/multikey/v1
SHA2-256 Digest:
ba2c182de2d92f7e47184bcca8fcf0beaee6d3986c527bf664c195bbc7c58597
|
URL:
https://w3id.org/security/jwk/v1
SHA2-256 Digest:
0f14b62f6071aafe00df265770ea0c7508e118247d79b7d861a406d2aa00bece
|
It
is
possible
to
confirm
the
cryptographic
digests
listed
above
by
running
a
command
like
the
following
(replacing
<DOCUMENT_URL>
with
the
appropriate
value)
through
a
modern
UNIX-like
OS
command
line
interface:
curl
-sL
-H
"Accept:
application/ld+json"
<DOCUMENT_URL>
|
openssl
dgst
-sha256
The
security
vocabulary
terms
that
the
JSON-LD
contexts
listed
above
resolve
to
are
in
the
https://w3id.org/security#
namespace.
That
is,
all
security
terms
in
this
vocabulary
are
of
the
form
https://w3id.org/security#TERM
,
where
TERM
is
the
name
of
a
term.
Implementations that perform RDF processing MUST treat the JSON-LD serialization of the vocabulary URL as already dereferenced, where the dereferenced document matches the corresponding hash value below.
Beyond
the
security
terms
defined
by
this
specification,
the
https://w3id.org/security#
namespace
also
includes
the
terms
defined
in
the
Controlled
Identifier
Document
1.0
Identifiers
(CIDs)
v1.0
[
CONTROLLER-DOCUMENT
]
specification,
with
the
corresponding
mappings
in
the
context
files
listed
above.
When dereferencing the https://w3id.org/security# URL, the media type of the data that is returned depends on HTTP content negotiation. These are as follows:
Media Type | Description and Hash |
---|---|
application/ld+json |
The
vocabulary
in
JSON-LD
format
[
JSON-LD11
].
SHA2-256 Digest:
|
text/turtle |
The
vocabulary
in
Turtle
format
[
TURTLE
].
SHA2-256 Digest:
|
text/html |
The
vocabulary
in
HTML+RDFa
Format
[
HTML-RDFA
].
SHA2-256 Digest:
|
It
is
possible
to
confirm
the
cryptographic
digests
listed
above
by
running
a
command
like
the
following
(replacing
<MEDIA_TYPE>
and
<DOCUMENT_URL>
with
the
appropriate
values)
through
a
modern
UNIX-like
OS
command
line
interface:
curl
-sL
-H
"Accept:
<MEDIA_TYPE>"
<DOCUMENT_URL>
|
openssl
dgst
-sha256
Authors of application-specific vocabularies and specifications SHOULD ensure that their JSON-LD context and vocabulary files are permanently cacheable using the approaches to caching described above or a functionally equivalent mechanism.
Implementations MAY load application-specific JSON-LD context files from the network during development, but SHOULD permanently cache JSON-LD context files used by conforming secured documents in production settings, to increase their security and privacy characteristics. Goals of processing speed MAY be achieved through caching approaches such as those described above or functionally equivalent mechanisms.
Some applications, such as digital wallets, that are capable of holding arbitrary verifiable credentials or other data-integrity-protected documents, from any issuer and using any contexts, might need to be able to load externally linked resources, such as JSON-LD context files, in production settings. This is expected to increase user choice, scalability, and decentralized upgrades in the ecosystem over time. Authors of such applications are advised to read the security and privacy sections of this document for further considerations.
For further information regarding processing of JSON-LD contexts and vocabularies, see Verifiable Credentials v2.0: Base Context and Verifiable Credentials v2.0: Vocabularies .
It is necessary to ensure that a consuming application has explicitly approved of the types, and therefore the semantics, of input documents that it will process. Not checking JSON-LD context values against known good values can lead to security vulnerabilities, due to variance in the semantics that they convey. Applications MUST use the algorithm in Section 4.6 Context Validation , or one that achieves equivalent protections, to validate contexts in a conforming secured document . Context validation MUST be run after running the applicable algorithm in either Section 4.4 Verify Proof or Section 4.5 Verify Proof Sets and Chains .
While the algorithm described in Section 4.6 Context Validation provides one way of checking context values, and one optional way of safely processing unknown context values, implementers MAY use alternative approaches, or a different ordering of the steps, that provide the same protections.
For example, if no JSON-LD processing is to occur, then, rather than performing this check, an application could follow the guidance in whatever trusted documentation is provided out of band for properly understanding the semantics of that type of document.
Another approach would be to configure an application to use a JSON-LD Context loader, sometimes referred to as a document loader, to use only local copies of approved context files. This would guarantee that neither the context files nor their cryptographic hashes would ever change, effectively resulting in the same result as the algorithm in Section 4.6 Context Validation .
Another alternative approach, also effectively equivalent to the algorithm in Section 4.6 Context Validation , would be for an application to keep a list of well known context URLs and their associated approved cryptographic hashes, without storing every context file locally. This would allow these contexts to be safely loaded from the network without compromising the security expectations of the application.
Yet
another
valid
approach
would
be
for
a
transmitting
application
to
compact
a
document
to
exactly
what
a
receiving
application
requests,
via
a
protocol
such
as
one
requesting
a
verifiable
presentation
,
omitting
additional
sender-specific
context
values
that
were
used
when
securing
the
original
document.
As
long
as
the
cryptography
suite's
verification
algorithm
provides
a
successful
verification
result,
such
transformations
are
valid
and
would
result
in
full
URLs
for
terms
that
were
previously
compacted
by
the
omitted
context.
That
is,
a
term
that
was
previously
compacted
to
foo
based
on
a
sender-supplied
context
that
is
unknown
to
a
receiver
(e.g.,
`
https://ontology.example/v1
)
would
instead
be
"expanded"
to
a
URL
like
https://ontology.example#foo
,
which
would
then
be
"compacted"
to
the
same
URL,
once
the
unknown
context
is
omitted
and
the
JSON-LD
compaction
algorithm
is
applied
by
the
receiving
application.
The
@context
property
is
used
to
ensure
that
implementations
are
using
the
same
semantics
when
terms
in
this
specification
are
processed.
For
example,
this
can
be
important
when
properties
like
type
are
processed
and
its
value,
such
as
DataIntegrityProof
,
are
used.
When
an
application
is
securing
a
document,
if
an
@context
property
is
not
provided
in
the
document
or
the
Data
Integrity
terms
used
in
the
document
are
not
mapped
by
existing
values
in
the
@context
property,
implementations
SHOULD
inject
or
append
an
@context
property
with
a
value
of
https://w3id.org/security/data-integrity/v2
or
one
or
more
contexts
with
at
least
the
same
declarations,
such
as
the
Verifiable
Credential
Data
Model
v2.0
context
(
https://www.w3.org/ns/credentials/v2
).
Implementations
that
do
not
intend
to
use
JSON-LD
processing
MAY
choose
to
not
include
an
@context
declaration
at
the
top-level
of
the
document.
However,
if
an
@context
declaration
is
not
included,
extensions
(such
as
the
addition
of
new
properties)
related
to
this
specification
or
corresponding
cryptosuites
MUST
NOT
be
made.
HTML processors are designed to continue processing if recoverable errors are detected. JSON-LD processors operate in a similar manner. This design philosophy was meant to ensure that developers could use only the parts of the JSON-LD language that they find useful, without causing the processor to throw errors on things that might not be important to the developer. Among other effects, this philosophy led to JSON-LD processors being designed to not throw errors, but rather warn developers, when encountering things such as undefined terms.
When converting from JSON-LD to an RDF Dataset, such as when canonicalizing a document [ RDF-CANON ], undefined terms and relative URLs can be dropped silently. When values are dropped, they are not protected by a digital proof. This creates a mismatch of expectations, where a developer, who is unaware of how a JSON-LD processor works, might think that certain data was being secured, and then be surprised to find that it was not, when no error was thrown. This specification requires that any recoverable loss of data when performing JSON-LD transformations result in an error, to avoid a mismatch in the security expectations of developers.
Implementations
that
use
JSON-LD
processing,
such
as
RDF
Dataset
Canonicalization
[
RDF-CANON
],
MUST
throw
an
error,
which
SHOULD
be
DATA_LOSS_DETECTION_ERROR
,
when
data
is
dropped
by
a
JSON-LD
processor,
such
as
when
an
undefined
term
is
detected
in
an
input
document.
Similarly, since conforming secured documents can be transferred from one security domain to another, conforming processors that process the conforming secured document cannot assume any particular base URL for the document. When deserializing to RDF, implementations MUST ensure that the base URL is set to null.
This section defines datatypes that are used by this specification.
This
specification
encodes
cryptographic
suite
identifiers
as
enumerable
strings,
which
is
useful
in
processes
that
need
to
efficiently
encode
such
strings,
such
as
compression
algorithms.
In
environments
that
support
data
types
for
string
values,
such
as
RDF
[
RDF-CONCEPTS
],
cryptographic
identifier
content
is
indicated
using
a
literal
value
whose
datatype
is
set
to
https://w3id.org/security#cryptosuiteString
.
The
cryptosuiteString
datatype
is
defined
as
follows:
https://w3id.org/security#cryptosuiteString
cryptosuite
property,
as
defined
in
Section
3.1
DataIntegrityProof
.
The term Linked Data is used to describe a recommended best practice for exposing, sharing, and connecting information on the Web using standards, such as URLs, to identify things and their properties. When information is presented as Linked Data, other related information can be easily discovered and new information can be easily linked to it. Linked Data is extensible in a decentralized way, greatly reducing barriers to large scale integration.
With the increase in usage of Linked Data for a variety of applications, there is a need to be able to verify the authenticity and integrity of Linked Data documents. This specification adds authentication and integrity protection to data documents through the use of mathematical proofs without sacrificing Linked Data features such as extensibility and composability.
While this specification provides mechanisms to digitally sign Linked Data, the use of Linked Data is not necessary to gain some of the advantages provided by this specification.
Cryptographic suites that implement this specification can be used to secure verifiable credentials and verifiable presentations . Implementers that are addressing those use cases are cautioned that additional checks might be appropriate when processing those types of documents.
There
are
some
use
cases
where
it
is
important
to
ensure
that
the
verification
method
used
in
a
proof
is
associated
with
the
issuer
in
a
verifiable
credential
,
or
the
holder
in
a
verifiable
presentation
,
during
the
process
of
validation
.
One
way
to
check
for
such
an
association
is
to
ensure
that
the
value
of
the
controller
property
of
a
proof's
verification
method
matches
the
URL
value
used
to
identify
the
issuer
or
holder
,
respectively,
and
that
the
verification
method
is
expressed
under
a
verification
relationship
that
is
acceptable
given
the
proof's
purpose.
This
particular
association
indicates
that
the
issuer
or
holder
,
respectively,
is
the
controller
of
the
verification
method
used
to
verify
the
proof.
Document
authors
and
implementers
are
advised
to
understand
the
difference
between
the
validity
period
of
a
proof
,
which
is
expressed
using
the
created
and
expires
properties,
and
the
validity
period
of
a
credential
,
which
is
expressed
using
the
validFrom
and
validUntil
properties.
While
these
properties
might
sometimes
express
the
same
validity
periods,
at
other
times
they
might
not
be
aligned.
When
verifying
a
proof
,
it
is
important
to
ensure
that
the
time
of
interest
(which
might
be
the
current
time
or
any
other
time)
is
within
the
validity
period
for
the
proof
(that
is,
between
created
and
expires
).
When
validating
a
verifiable
credential
,
it
is
important
to
ensure
that
the
time
of
interest
is
within
the
validity
period
for
the
credential
(that
is,
betweeen
validFrom
and
validUntil
).
Note
that
a
failure
to
validate
either
the
validity
period
for
the
proof
,
or
the
validity
period
for
the
credential
,
might
result
in
accepting
data
that
ought
to
have
been
rejected.
Finally,
implementers
are
also
urged
to
understand
that
there
is
a
difference
between
the
revocation
information
associated
with
a
verifiable
credential
,
and
the
revocation
and
expiration
times
for
a
verification
method
.
The
revocation
and
expiration
times
for
a
verification
method
are
expressed
using
the
revocation
and
expires
properties,
respectively;
are
related
to
events
such
as
a
secret
key
being
compromised
or
expiring;
and
can
provide
timing
information
which
might
reveal
details
about
a
controller,
such
as
their
security
practices
or
when
they
might
have
been
compromised.
The
revocation
information
for
a
verifiable
credential
is
expressed
using
the
credentialStatus
property;
is
related
to
events
such
as
an
individual
losing
the
privilege
that
is
granted
by
the
verifiable
credential
;
and
does
not
provide
timing
information,
which
enhances
privacy.
A
data
integrity
proof
is
designed
to
be
easy
to
use
by
developers
and
therefore
strives
to
minimize
the
amount
of
information
one
has
to
remember
to
generate
a
proof.
Often,
just
the
cryptographic
suite
name
(such
as
eddsa-rdfc-2022
)
is
required
from
developers
to
initiate
the
creation
of
a
proof.
These
cryptographic
suite
s
are
often
created
and
reviewed
by
people
that
have
the
requisite
cryptographic
training
to
ensure
that
safe
combinations
of
cryptographic
primitives
are
used.
This
section
specifies
the
requirements
for
authoring
cryptographic
suite
specifications.
The requirements for all data integrity cryptographic suite specifications are as follows:
type
and
any
parameters
that
can
be
used
with
the
suite.
true
if
the
verification
succeeded,
or
false
otherwise.
true
,
or
null
otherwise.
@protected
keyword.
A cryptosuite instance is instantiated using a cryptosuite instantiation algorithm and is made available to algorithms in an implementation-specific manner. Implementations MAY use the Verifiable Credential Extensions document to discover known cryptosuite instantiation algorithms .
A
number
of
cryptographic
suites
follow
the
same
basic
pattern
when
expressing
a
data
integrity
proof
.
This
section
specifies
that
general
design
pattern,
a
cryptographic
suite
type
called
a
DataIntegrityProof
,
which
reduces
the
burden
of
writing
and
implementing
cryptographic
suites
through
the
reuse
of
design
primitives
and
source
code.
When
specifing
a
cryptographic
suite
that
utilizes
this
design
pattern,
the
proof
value
takes
the
following
form:
type
property
MUST
contain
the
string
DataIntegrityProof
.
cryptosuite
property
MUST
be
a
string
that
identifies
the
cryptographic
suite
.
If
the
processing
environment
supports
string
subtypes,
the
subtype
of
the
cryptosuite
value
MUST
be
the
https://w3id.org/security#cryptosuiteString
subtype.
proofValue
property
MUST
be
used,
as
specified
in
Section
2.1
Proofs
.
Cryptographic
suite
designers
MUST
use
mandatory
proof
value
properties
defined
in
Section
2.1
Proofs
,
and
MAY
define
other
properties
specific
to
their
cryptographic
suite.
One
of
the
design
patterns
seen
in
Data
Integrity
cryptosuites
from
2012
to
2020
was
use
of
the
type
property
to
establish
a
specific
type
for
a
cryptographic
suite;
the
Ed25519Signature2020
cryptographic
suite
was
one
such
specification.
This
led
to
a
greater
burden
on
cryptographic
suite
implementations,
where
every
new
cryptographic
suite
required
specification
of
a
new
JSON-LD
Context,
resulting
in
a
sub-optimal
developer
experience.
A
streamlined
version
of
this
design
pattern
emerged
in
2020,
such
that
a
developer
would
only
need
to
include
a
single
JSON-LD
Context
to
support
all
modern
cryptographic
suites.
This
encouraged
more
modern
cryptosuites
—
such
as
the
EdDSA
Cryptosuites
[
DI-EDDSA
]
and
the
ECDSA
Cryptosuites
[
DI-ECDSA
]
—
to
be
built
based
on
the
streamlined
pattern
described
in
this
section.
To
improve
the
developer
experience,
authors
creating
new
Data
Integrity
cryptographic
suite
specifications
SHOULD
use
the
modern
pattern
—
where
the
type
is
set
to
DataIntegrityProof
;
the
cryptosuite
property
carries
the
identifier
for
the
cryptosuite;
and
any
cryptosuite-specific
cryptographic
data
is
encapsulated
(i.e.,
not
directly
exposed
as
application
layer
data)
within
proofValue
.
A
list
of
cryptographic
suite
specifications
that
are
known
to
follow
this
pattern
is
provided
in
the
Securing
Mechanisms
section
of
the
Verifiable
Credentials
Extensions
document.
The algorithms defined below operate on documents represented as JSON objects . This specification follows the JSON-LD 1.1 Processing Algorithms and API specification in representing a JSON object as a map . An unsecured data document is a map that contains no proof values. An input document is an map that has not yet had the current proof added to it, but it MAY contain a proof value that was added to it by a previous process. A secured data document is a map that contains one or more proof values.
Implementers MAY implement reasonable defaults and safeguards in addition to the algorithms below, to help mitigate developer error, excessive resource consumption, newly discovered attack models against which there is a particular protection, and other improvements. The algorithms provided below are the minimum requirements for an interoperable implementation, and developers are urged to include additional measures that could contribute to a safer and more efficient ecosystem.
The processing model used by a conforming processor and its application-specific software is described in this section. When software is to ensure information is tamper-evident, it performs the following steps:
@context
property.
When software needs to use information that was transmitted to it using a mechanism described by this specification, it performs the following steps:
The following algorithm specifies how a digital proof can be added to an input document , and can then be used to verify the output document's authenticity and integrity. Required inputs are an input document ( map inputDocument ), a cryptosuite instance ( struct cryptosuite ), and a set of options ( map options ). Output is a secured data document ( map ) or an error. Whenever this algorithm encodes strings, it MUST use UTF-8 encoding.
The following algorithm specifies how to incrementally add a proof to a proof set or proof chain starting with a secured document containing either a proof or proof set/chain. Required inputs are a secured data document ( map securedDocument ), a cryptographic suite ( cryptosuite instance suite ), and a set of options ( map options ). Output is a new secured data document ( map ). Whenever this algorithm encodes strings, it MUST use UTF-8 encoding.
previousProof
item
that
is
a
string,
add
the
element
from
allProofs
with
an
id
attribute
matching
previousProof
to
matchingProofs
.
If
a
proof
with
id
equal
to
previousProof
does
not
exist
in
allProofs
,
an
error
MUST
be
raised
and
SHOULD
convey
an
error
type
of
PROOF_GENERATION_ERROR
.
previousProof
item
that
is
an
array,
add
each
element
from
allProofs
with
an
id
attribute
that
matches
an
element
of
that
array.
If
any
element
of
previousProof
list
has
an
id
attribute
that
does
not
match
the
id
attribute
of
any
element
of
allProofs
,
an
error
MUST
be
raised
and
SHOULD
convey
an
error
type
of
PROOF_GENERATION_ERROR
.
This
step
adds
references
to
the
named
graphs
,
as
well
as
adding
a
copy
of
all
the
claims
contained
in
the
proof
graphs
.
The
step
is
critical,
as
it
binds
any
matching
proofs
to
the
document
prior
to
applying
the
current
proof.
The
proof
value
for
the
document
will
be
updated
in
a
later
step
of
this
algorithm.
The following algorithm specifies how to check the authenticity and integrity of a secured data document by verifying its digital proof. The algorithm takes as input:
This algorithm returns a verification result , a struct whose items are:
true
or
false
false
;
otherwise,
an
input
document
false
;
otherwise,
a
media
type
,
which
MAY
include
parameters
When
a
step
says
"an
error
MUST
be
raised",
it
means
that
a
verification
result
MUST
be
returned
with
a
verified
value
of
false
and
a
non-empty
errors
list.
In
a
proof
set
or
proof
chain
,
a
secured
data
document
has
a
proof
attribute
which
contains
a
list
of
proofs
(
allProofs
).
The
following
algorithm
provides
one
method
of
checking
the
authenticity
and
integrity
of
a
secured
data
document
,
achieved
by
verifying
every
proof
in
allProofs
.
Other
approaches
are
possible,
particularly
if
it
is
only
desired
to
verify
a
subset
of
the
proofs
contained
in
allProofs
.
If
another
approach
is
taken
to
verify
only
a
subset
of
the
proofs,
then
it
is
important
to
note
that
any
proof
in
that
subset
with
a
previousProof
can
only
be
considered
verified
if
the
proofs
it
references
are
also
considered
verified.
Required input is a secured data document ( securedDocument ). A list of verification results corresponding to each proof in allProofs is generated, and a single combined verification result is returned as output. Implementations MAY return any of the other verification result s and/or any other metadata alongside the combined verification result .
previousProof
attribute
and
the
value
of
that
attribute
is
a
string
,
add
the
element
from
allProofs
with
an
id
attribute
value
matching
the
value
of
previousProof
to
matchingProofs
.
If
a
proof
with
id
value
equal
to
the
value
of
previousProof
does
not
exist
in
allProofs
,
an
error
MUST
be
raised
and
SHOULD
convey
an
error
type
of
PROOF_VERIFICATION_ERROR
.
If
the
previousProof
attribute
is
a
list
,
add
each
element
from
allProofs
with
an
id
attribute
value
that
matches
the
value
of
an
element
of
that
list
.
If
any
element
of
previousProof
list
has
an
id
attribute
value
that
does
not
match
the
id
attribute
value
of
any
element
of
allProofs
,
an
error
MUST
be
raised
and
SHOULD
convey
an
error
type
of
PROOF_VERIFICATION_ERROR
.
See the note in Step 6 of Section 4.3 Add Proof Set/Chain to learn about what document properties and previous proofs this step secures.
true
,
combinedVerificationResult
.
document
to
null
,
and
combinedVerificationResult
.
mediaType
to
null
.
false
,
set
combinedVerificationResult
.
verified
to
false
.
false
,
set
combinedVerificationResult
.
document
to
null
and
combinedVerificationResult
.
mediaType
to
null
.
The following algorithm provides one mechanism that can be used to ensure that an application understands the contexts associated with a document before it executed business rules specific to the input in the document. For more rationale related to this algorithm, see Section 2.4.1 Validating Contexts . This algorithm takes inputs of a document ( map inputDocument ), a set of known JSON-LD Contexts ( list knownContext ), and a boolean to recompact when unknown contexts are detected ( boolean recompact ).
This algorithm returns a context validation result , a struct whose items are:
true
or
false
false
;
otherwise,
an
input
document
The context validation algorithm is as follows:
false
,
result
.
warnings
to
an
empty
list,
result
.
errors
to
an
empty
list,
compactionContext
to
an
empty
list;
and
clone
inputDocument
to
result
.
validatedDocument
.
@context
property
of
result
.
validatedDocument
,
which
might
be
undefined.
@context
property,
or
any
URI
in
contextValue
dereferences
to
a
JSON-LD
Context
file
that
does
not
match
a
known
good
value
or
cryptographic
hash,
then
perform
the
applicable
action:
true
,
set
result
.
validatedDocument
to
the
result
of
running
the
JSON-LD
Compaction
Algorithm
with
the
inputDocument
and
knownContext
as
inputs.
If
the
compaction
fails,
add
at
least
one
error
to
result
.
errors
.
true
,
add
at
least
one
error
to
result
.
errors
.
true
;
otherwise,
set
result
.
validated
to
false
,
and
remove
the
document
property
from
result
.
Implementations MAY include additional warnings or errors that enforce further validation rules that are specific to the implementation or a particular use case.
The
algorithms
described
in
this
specification,
as
well
as
in
various
cryptographic
suite
specifications,
throw
specific
types
of
errors.
Implementers
might
find
it
useful
to
convey
these
errors
to
other
libraries
or
software
systems.
This
section
provides
specific
URLs,
descriptions,
URLs
and
error
codes
descriptions
for
the
errors,
such
that
an
ecosystem
implementing
technologies
described
by
this
specification
might
interoperate
more
effectively
when
errors
occur.
When exposing these errors through an HTTP interface, implementers SHOULD use [ RFC9457 ] to encode the error data structure as a ProblemDetails map . If [ RFC9457 ] is used:
type
value
of
the
error
object
MUST
be
a
URL
that
starts
with
the
value
https://w3id.org/security#
and
ends
with
the
value
in
the
section
listed
below.
code
value
MUST
be
the
integer
code
described
in
the
table
below
(in
parentheses,
beside
the
type
name).
The
title
value
SHOULD
provide
a
short
but
specific
human-readable
string
for
the
error.
detail
value
MUST
be
present
and
SHOULD
provide
a
longer
human-readable
string
for
the
error.
domain
value
in
a
proof
did
not
match
the
expected
value.
See
Section
4.4
Verify
Proof
.
challenge
value
in
a
proof
did
not
match
the
expected
value.
See
Section
4.4
Verify
Proof
.
The following section describes security considerations that developers implementing this specification should be aware of in order to create secure software.
Cryptography secures information through the use of secrets. Knowledge of the necessary secret makes it computationally easy to access certain information. The same information can be accessed if a computationally-difficult, brute-force effort successfully guesses the secret. All modern cryptography requires the computationally difficult approach to remain difficult throughout time, which does not always hold due to breakthroughs in science and mathematics. That is to say that Cryptography has a shelf life .
This specification plans for the obsolescence of all cryptographic approaches by asserting that whatever cryptography is in use today is highly likely to be broken over time. Software systems have to be able to change the cryptography in use over time in order to continue to secure information. Such changes might involve increasing required secret sizes or modifications to the cryptographic primitives used. However, some combinations of cryptographic parameters might actually reduce security. Given these assumptions, systems need to be able to distinguish different combinations of safe cryptographic parameters, also known as cryptographic suites, from one another. When identifying or versioning cryptographic suites, there are several approaches that can be taken which include: parameters, numbers, and dates.
Parametric
versioning
specifies
the
particular
cryptographic
parameters
that
are
employed
in
a
cryptographic
suite.
For
example,
one
could
use
an
identifier
such
as
RSASSA-PKCS1-v1_5-SHA1
.
The
benefit
to
this
scheme
is
that
a
well-trained
cryptographer
will
be
able
to
determine
all
of
the
parameters
in
play
by
the
identifier.
The
drawback
to
this
scheme
is
that
most
of
the
population
that
uses
these
sorts
of
identifiers
are
not
well
trained
and
thus
will
not
understand
that
the
previously
mentioned
identifier
is
a
cryptographic
suite
that
is
no
longer
safe
to
use.
Additionally,
this
lack
of
knowledge
might
lead
software
developers
to
generalize
the
parsing
of
cryptographic
suite
identifiers
such
that
any
combination
of
cryptographic
primitives
becomes
acceptable,
resulting
in
reduced
security.
Ideally,
cryptographic
suites
are
implemented
in
software
as
specific,
acceptable
profiles
of
cryptographic
parameters
instead.
Numbered
versioning
might
specify
a
major
and
minor
version
number
such
as
1.0
or
2.1
.
Numbered
versioning
conveys
a
specific
order
and
suggests
that
higher
version
numbers
are
more
capable
than
lower
version
numbers.
The
benefit
of
this
approach
is
that
it
removes
complex
parameters
that
less
expert
developers
might
not
understand
with
a
simpler
model
that
conveys
that
an
upgrade
might
be
appropriate.
The
drawback
of
this
approach
is
that
its
not
clear
if
an
upgrade
is
necessary,
as
software
version
number
increases
often
don't
require
an
upgrade
for
the
software
to
continue
functioning.
This
can
lead
to
developers
thinking
their
usage
of
a
particular
version
is
safe,
when
it
is
not.
Ideally,
additional
signals
would
be
given
to
developers
that
use
cryptographic
suites
in
their
software
that
periodic
reviews
of
those
suites
for
continued
security
are
required.
Date-based versioning specifies a particular release date for a specific cryptographic suite. The benefit of a date, such as a year, is that it is immediately clear to a developer if the date is relatively old or new. Seeing an old date might prompt the developer to go searching for a newer cryptographic suite, where as a parametric or number-based versioning scheme might not. The downside of a date-based version is that some cryptographic suites might not expire for 5-10 years, prompting the developer to go searching for a newer cryptographic suite only to not find one that is newer. While this might be an inconvenience, it is one that results in safer ecosystem behavior.
Modern cryptographic algorithms provide a number of tunable parameters and options to ensure that the algorithms can meet the varied requirements of different use cases. For example, embedded systems have limited processing and memory environments and might not have the resources to generate the strongest digital signatures for a given algorithm. Other environments, like financial trading systems, might only need to protect data for a day while the trade is occurring, while other environments might need to protect data for multiple decades. To meet these needs, cryptographic algorithm designers often provide multiple ways to configure a cryptographic algorithm.
Cryptographic library implementers often take the specifications created by cryptographic algorithm designers and specification authors and implement them such that all options are available to the application developers that use their libraries. This can be due to not knowing which combination of features a particular application developer might need for a given cryptographic deployment. All options are often exposed to application developers.
Application developers that use cryptographic libraries often do not have the requisite cryptographic expertise and knowledge necessary to appropriately select cryptographic parameters and options for a given application. This lack of expertise can lead to an inappropriate selection of cryptographic parameters and options for a particular application.
This specification sets the priority of constituencies to protect application developers over cryptographic library implementers over cryptographic specification authors over cryptographic algorithm designers. Given these priorities, the following recommendations are made:
The guidance above is meant to ensure that useful cryptographic options and parameters are provided at the lower layers of the architecture while not exposing those options and parameters to application developers who may not fully understand the balancing benefits and drawbacks of each option.
Section 5.1 Versioning Cryptography Suites emphasized the importance of providing relatively easy to understand information concerning the timeliness of particular cryptographic suite, while section 5.2 Protecting Application Developers further emphasized minimizing the number of options to be specified. Indeed, section 3. Cryptographic Suites lists requirements for cryptographic suites which include detailed specification of algorithm, transformation, hashing, and serialization. Hence, the name of the cryptographic suite does not need to include all this detail, which implies the parametric versioning mentioned in section 5.1 Versioning Cryptography Suites is neither necessary nor desirable.
The recommended naming convention for cryptographic suites is a string composed of a signature algorithm identifier, separated by a hyphen from an option identifier (if the cryptosuite supports incompatible implementation options), followed by a hyphen and designation of the approximate year that the suite was proposed.
For
example,
the
[
DI-EDDSA
]
is
based
on
EdDSA
digital
signatures,
supports
two
incompatible
options
based
on
canonicalization
approaches,
and
was
proposed
in
roughly
the
year
2022,
so
it
would
have
two
different
cryptosuite
names:
eddsa-rdfc-2022
and
eddsa-jcs-2022
.
Although
the
[
DI-ECDSA
]
is
based
on
ECDSA
digital
signatures,
supports
the
same
two
incompatible
canonicalization
approaches
as
[
DI-EDDSA
],
and
supports
two
different
levels
of
security
(128
bit
and
192
bit)
via
two
alternative
sets
of
elliptic
curves
and
hashes,
it
has
only
two
cryptosuite
names:
ecdsa-rdfc-2019
and
ecdsa-jcs-2019
.
The
security
level
and
corresponding
curves
and
hashes
are
determined
from
the
multi-key
format
of
the
public
key
used
in
validation.
Cryptographic agility is a practice by which one designs frequently connected information security systems to support switching between multiple cryptographic primitives and/or algorithms . The primary goal of cryptographic agility is to enable systems to rapidly adapt to new cryptographic primitives and algorithms without making disruptive changes to the systems' infrastructure. Thus, when a particular cryptographic primitive, such as the SHA-1 algorithm, is determined to be no longer safe to use, systems can be reconfigured to use a newer primitive via a simple configuration file change.
Cryptographic agility is most effective when the client and the server in the information security system are in regular contact. However, when the messages protected by a particular cryptographic algorithm are long-lived, as with verifiable credentials , and/or when the client (holder) might not be able to easily recontact the server (issuer), then cryptographic agility does not provide the desired protections.
Cryptographic layering is a practice where one designs rarely connected information security systems to employ multiple primitives and/or algorithms at the same time . The primary goal of cryptographic layering is to enable systems to survive the failure or one or more cryptographic algorithms or primitives without losing cryptographic protection on the payload. For example, digitally signing a single piece of information using RSA, ECDSA, and Falcon algorithms in parallel would provide a mechanism that could survive the failure of two of these three digital signature algorithms. When a particular cryptographic protection is compromised, such as an RSA digital signature using 768-bit keys, systems can still utilize the non-compromised cryptographic protections to continue to protect the information. Developers are urged to take advantage of this feature for all signed content that might need to be protected for a year or longer.
This specification provides for both forms of agility. It provides for cryptographic agility, which allows one to easily switch from one algorithm to another. It also provides for cryptographic layering, which allows one to simultaneously use multiple cryptographic algorithms, typically in parallel, such that any of those used to protect information can be used without reliance on or requirement of the others, while still keeping the digital proof format easy to use for developers.
At times, it is beneficial to transform the data being protected during the cryptographic protection process. Such "in-line" transformation can enable a particular type of cryptographic protection to be agnostic to the data format it is carried in. For example, some Data Integrity cryptographic suites utilize RDF Dataset Canonicalization [ RDF-CANON ] which transforms the initial representation into a canonical form [ N-QUADS ] that is then serialized, hashed, and digitally signed. As long as any syntax expressing the protected data can be transformed into this canonical form, the digital signature can be verified. This enables the same digital signature over the information to be expressed in JSON, CBOR, YAML, and other compatible syntaxes without having to create a cryptographic proof for every syntax.
Being able to express the same digital signature across a variety of syntaxes is beneficial because systems often have native data formats with which they operate. For example, some systems are written against JSON data, while others are written against CBOR data. Without transformation, systems that process their data internally as CBOR are required to store the digitally signed data structures as JSON (or vice-versa). This leads to double-storing data and can lead to increased security attack surface if the unsigned representation stored in databases accidentally deviates from the signed representation. By using transformations, the digital proof can live in the native data format to help prevent otherwise undetectable database drift over time.
This specification is designed to avoid requiring the duplication of signed information by utilizing "in-line" data transformations. Application developers are urged to work with cryptographically protected data in the native data format for their application and not separate storage of cryptographic proofs from the data being protected. Developers are also urged to regularly confirm that the cryptographically protected data has not been tampered with as it is written to and read from application storage.
Some transformations, such as RDF Dataset Canonicalization [ RDF-CANON ], have mitigations for input data sets that can be used by attackers to consume excessive processing cycles. This class of attack is called dataset poisoning , and all modern RDF Dataset canonicalizers are required to detect these sorts of bad inputs and halt processing. The test suites for RDF Dataset Canonicalization includes such poisoned datasets to ensure that such mitigations exist in all conforming implementations. Generally speaking, cryptographic suite specifications that use transformations are required to mitigate these sorts of attacks, and implementers are urged to ensure that the software libraries that they use enforce these mitigations. These attacks are in the same general category as any resource starvation attack, such as HTTP clients that deliberately slow connections, thus starving connections on the server. Implementers are advised to consider these sorts of attacks when implementing defensive security strategies.
The data that is protected by any data integrity proof is the transformed data . Transformed data is generated by a transformation algorithm that is specified by a particular cryptosuite . This protection mechanism differs from some more traditional digital signature mechanisms that do not perform any sort of transformation on the input data. The benefits of transformation are detailed in Section 5.5 Transformations .
For example, cryptosuites such as ecdsa-jcs-2019 and eddsa-jcs-2022 use the JSON Canonicalization Scheme (JCS) to transform the data to canonicalized JSON, which is then cryptographically hashed and digitally signed. One benefit of this approach is that adding or removing formatting characters that do not impact the meaning of the information being signed, such as spaces, tabs, and newlines, does not invalidate the digital signature. More traditional digital signature mechanisms do not have this capability.
Other cryptosuites such as ecdsa-rdfc-2019 and eddsa-rdfc-2022 use RDF Dataset Canonicalization to transform the data to canonicalized N-Quads [ N-QUADS ], which is then cryptographically hashed and digitally signed. One benefit of this approach is that the cryptographic signature is portable to a variety of different syntaxes, such as JSON, YAML, and CBOR, without invalidating the signature. More traditional cryptographic signature mechanisms do not have this capability.
Implementers and developers are urged to not trust information that contains a data integrity proof unless the proof has been verified and the verified data is provided in a return value from a software library that has confirmed that all data returned has been successfully protected.
The inspectability of application data has effects on system efficiency and developer productivity. When cryptographically protected application data, such as base-encoded binary data, is not easily processed by application subsystems, such as databases, it increases the effort of working with the cryptographically protected information. For example, a cryptographically protected payload that can be natively stored and indexed by a database will result in a simpler system that:
Similarly, a cryptographically protected payload that can be processed by multiple upstream networked systems increases the ability to properly layer security architectures. For example, if upstream systems do not have to repeatedly decode the incoming payload, it increases the ability for a system to distribute processing load by specializing upstream subsystems to actively combat attacks. While a digital signature needs to always be checked before taking substantive action, other upstream checks can be performed on transparent payloads — such as identifier-based rate limiting, signature expiration checking, or nonce/challenge checking — to reject obviously bad requests.
Additionally, if a developer is not able to easily view data in a system, the ability to easily audit or debug system correctness is hampered. For example, requiring application developers to cut-and-paste base-encoded application data makes development more challenging and increases the chances that obvious bugs will be missed because every message needs to go through a manually operated base-decoding tool.
There are times, however, where the correct design decision is to make data opaque. Data that does not need to be processed by other application subsystems, as well as data that does not need to be modified or accessed by an application developer, can be serialized into opaque formats. Examples include digital signature values, cryptographic key parameters, and other data fields that only need to be accessed by a cryptographic library and need not be modified by the application developer. There are also examples where data opacity is appropriate when the underlying subsystem does not expose the application developer to the underlying complexity of the opaque data, such as databases that perform encryption at rest. In these cases, the application developer continues to develop against transparent application data formats while the database manages the complexity of encrypting and decrypting the application data to and from long-term storage.
This specification strives to provide an architecture where application data remains in its native format and is not made opaque, while other cryptographic data, such as digital signatures, are kept in their opaque binary encoded form. Cryptographic suite implementers are urged to consider appropriate use of data opacity when designing their suites, and to weigh the design trade-offs when making application data opaque versus providing access to cryptographic data at the application layer.
Implementers ensure that a verification method is bound to a particular controller by going from the definition of the verification method to the controller document , and then ensuring that the controller document also contains a reference to the verification method . This process is described in the algorithm for retrieving a verification method .
When an implementation is verifying a proof , it is imperative that it verify not only that the verification method used to generate the proof is listed in the controller document , but also that it was intended to be used to generate the proof that is being verified. This process is known as "verification relationship validation".
The
process
of
validating
a
verification
relationship
is
outlined
in
Section
3.3
Retrieve
Verification
Method
of
the
Controlled
Identifier
Document
1.0
Identifiers
(CIDs)
v1.0
specification.
This process is used to ensure that cryptographic material, such as a private cryptographic key, is not misused by application to an unintended purpose. An example of cryptographic material misuse would be if a private cryptographic key meant to be used to issue a verifiable credential was instead used to log into a website (that is, for authentication). Not checking a verification relationship is dangerous because the restriction and protection profile for some cryptographic material could be determined by its intended use. For example, some applications could be trusted to use cryptographic material for only one purpose, or some cryptographic material could be more protected, such as through storage in a hardware security module in a data center versus as an unencrypted file on a laptop.
When an implementation is verifying a proof , it is imperative that it verify that the proof purpose match the intended use.
This process is used to ensure that proofs are not misused by an application for an unintended purpose, as this is dangerous for the proof creator. An example of misuse would be if a proof that stated its purpose was for securing assertions in verifiable credentials was instead used for authentication to log into a website. In this case, the proof creator attached proofs to any number of verifiable credentials that they expected to be distributed to an unbounded number of other parties. Any one of these parties could log into a website as the proof creator if the website erroneously accepted such a proof as authentication instead of its intended purpose.
The way in which a transformation, such as canonicalization, is performed can affect the security characteristics of a system. Selecting the best canonicalization mechanisms depends on the use case. Often, the simplest mechanism that satisfies the desired security requirements is the best choice. This section attempts to provide simple guidance to help implementers choose between the two main canonicalization mechanisms referred to in this specification, namely JSON Canonicalization Scheme [ RFC8785 ] and RDF Dataset Canonicalization [ RDF-CANON ].
If an application only uses JSON and does not depend on any form of RDF semantics, then using a cryptography suite that uses JSON Canonicalization Scheme [ RFC8785 ] is an attractive approach.
If an application uses JSON-LD and needs to secure the semantics of the document, then using a cryptography suite that uses RDF Dataset Canonicalization [ RDF-CANON ] is an attractive approach.
Implementers are also advised that other mechanisms that perform no transformations are available, that secure the data by wrapping it in a cryptographic envelope instead of embedding the proof in the data, such as JWTs [ RFC7519 ] and CWTs [ RFC8392 ]. These approaches have simplicity advantages in some use cases, at the expense of some of the benefits provided by the approach detailed in this specification.
One of the algorithmic processes used by this specification is canonicalization, which is a type of transformation . Canonicalization is the process of taking information that might be expressed in a variety of semantically equivalent ways as input, and expressing all output in a single way, called a "canonical form".
The security of a resulting data integrity proof that utilizes canonicalization is highly dependent on the correctness of the algorithm. For example, if a canonicalization algorithm converts two inputs that have different meanings into the same output, then the author's intentions can be misrepresented to a verifier . This can be used as an attack vector by adversaries.
Additionally, if semantically relevant information in an input is not present in the output, then an attacker could insert such information into a message without causing proof verification to fail. This is similar to another transformation that is commonly used when cryptographically signing messages: cryptographic hashing. If an attacker is able to produce the same cryptographic hash from a different input, then the cryptographic hash algorithm is not considered secure.
Implementers are strongly urged to ensure proper vetting of any canonicalization algorithms to be used for transformation of input to a hashing process. Proper vetting includes, at a minimum, association with a peer reviewed mathematical proof of algorithm correctness; multiple implementations and vetting by experts in a standards setting organization is preferred. Implementers are strongly urged not to invent or use new mechanisms unless they have formal training in information canonicalization and/or access to experts in the field who are capable of producing a peer reviewed mathematical proof of algorithm correctness.
This specification is designed in such a way that no network requests are required when verifying a proof on a conforming secured document . Readers might note, however, that JSON-LD contexts and verification methods can contain URLs that might be retrieved over a network connection. This concern exists for any URL that might be loaded from the network during or after verification.
To
the
extent
possible,
implementers
are
urged
to
permanently
or
aggressively
cache
such
information
to
reduce
the
attack
surface
on
an
implementation
that
might
need
to
fetch
such
URLs
over
the
network.
For
example,
caching
techniques
for
JSON-LD
contexts
are
described
in
Section
2.4
Contexts
and
Vocabularies
,
and
some
verification
methods
,
such
as
did:key
[
DID-KEY
],
do
not
need
to
be
fetched
from
the
network
at
all.
When it is not possible to use cached information, such as when a specific HTTP URL-based instance of a verification method is encountered for the first time, implementers are cautioned to use defensive measures to mitigate denial-of-service attacks during any process that might fetch a resource from the network.
Since the technology to secure documents described by this specification is generalized in nature, the security implications of its use might not be immediately apparent to readers. To understand the sort of security concerns one might need to consider in a complete software system, implementers are urged to read about how this technology is used in the verifiable credentials ecosystem [ VC-DATA-MODEL-2.0 ]; see the section on Verifiable Credential Security Considerations for more information.
The following section describes privacy considerations that developers implementing this specification should be aware of in order to create privacy enhancing software.
When a digitally-signed payload contains data that is seen by multiple verifiers, it becomes a point of correlation. An example of such data is a shopping loyalty card number. Correlatable data can be used for tracking purposes by verifiers, which can sometimes violate privacy expectations. The fact that some data can be used for tracking might not be immediately apparent. Examples of such correlatable data include, but are not limited to, a static digital signature or a cryptographic hash of an image.
It is possible to create a digitally-signed payload that does not have any correlatable tracking data while also providing some level of assurance that the payload is trustworthy for a given interaction. This characteristic is called unlinkability which ensures that no correlatable data are used in a digitally-signed payload while still providing some level of trust, the sufficiency of which has to be determined by each verifier.
It is important to understand that not all use cases require or even permit unlinkability. There are use cases where linkability and correlation are required due to regulatory or safety reasons, such as correlating organizations and individuals that are shipping and storing hazardous materials. Unlinkability is useful when there is an expectation of privacy for a particular interaction.
There are at least two mechanisms that can provide some level of unlinkability. The first method is to ensure that no data value used in the message is ever repeated in a future message. The second is to ensure that any repeated data value provides adequate herd privacy such that it becomes practically impossible to correlate the entity that expects some level of privacy in the interaction.
A variety of methods can be used to achieve unlinkability. These methods include ensuring that a message is a single use bearer token with no information that can be used for the purposes of correlation, using attributes that ensure an adequate level of herd privacy, and the use of cryptosuites that enable the entity presenting a message to regenerate new signatures while not compromising the trust in the message being presented.
Selective disclosure is a technique that enables the recipient of a previously-signed message (that is, a message signed by its creator) to reveal only parts of the message without disturbing the verifiability of those parts. For example, one might selectively disclose a digital driver's license for the purpose of renting a car. This could involve revealing only the issuing authority, license number, birthday, and authorized motor vehicle class from the license. Note that in this case, the license number is correlatable information, but some amount of privacy is preserved because the driver's full name and address are not shared.
Not
all
software
or
cryptosuites
are
capable
of
providing
selective
disclosure.
If
the
author
of
a
message
wishes
it
to
be
selectively
disclosable
by
its
recipient,
then
they
need
to
enable
selective
disclosure
on
the
specific
message,
and
both
need
to
use
a
capable
cryptosuite.
The
author
might
also
make
it
mandatory
to
disclose
certain
parts
of
the
message.
A
recipient
that
wants
to
selectively
disclose
partial
content
of
the
message
needs
to
utilize
software
that
is
able
to
perform
the
technique.
An
example
of
a
cryptosuite
that
supports
selective
disclosure
is
bbs-2023
.
It is possible to selectively disclose information in a way that does not preserve unlinkability. For example, one might want to disclose the inspection results related to a shipment, which include the shipment identifier or lot number, which might have to be correlatable due to regulatory requirements. However, disclosure of the entire inspection result might not be required as selectively disclosing just the pass/fail status could be deemed adequate. For more information on disclosing information while preserving privacy, see Section 6.1 Unlinkability .
When
using
the
previousProof
feature
defined
in
2.1.2
Proof
Chains
,
implementations
are
required
to
digitally
sign
over
one
or
more
previous
proofs,
so
as
to
include
them
in
the
secured
payload.
This
inevitably
exposes
information
related
to
each
entity
that
added
a
previous
proof.
At minimum, the verification method for the previous proof, such as a public key, is seen by the creator of the next proof in a proof chain. This can be a privacy concern if the creator of the previous proof did not intend to be included in a proof chain, but is an inevitable outcome when adding a non-repudiable digital signature to a document of any kind.
It is possible to use more advanced cryptographic mechanisms, such as a group signature , to hide the identity of the signer of a message, and it is also possible for a Data Integrity cryptographic suite to mitigate this privacy concern.
Fingerprinting concerns exist for any URL that might be loaded from the network during or after proof verification . This specification is designed in such a way that no network requests are necessary when verifying a proof on a conforming secured document . Readers might note, however, that JSON-LD contexts and verification methods can contain resource URLs that might be retrieved over a network connection leading to fingerprinting concerns.
For example, creators of conforming secured documents might craft unique per-document URLs for JSON-LD contexts and verification methods . When verifying such a document, a verifier fetching that information from the network would reveal their interest in the conforming secured document to the creator of the document, which might lead to a mismatch in privacy expectations for any entity that is not the creator of the document.
Implementers are urged to follow the guidance in Section 5.13 Network Requests on URL caching and implementing defensively when fetching URLs from the network. Usage of techniques such as Oblivious HTTP to retrieve resources from the network, without revealing the client that is making the request, are encouraged. Additionally, heuristics might be used to determine whether creators of conforming secured documents are using fingerprinting URLs in a way that might violate privacy expectations. These heuristics could be used to display warnings to entities that might process documents containing suspected fingerprinting URLs.
The way in which a transformation, namely canonicalization, is performed can affect the privacy characteristics of a system. Selecting the best canonicalization mechanism depends on the use case. This section attempts to provide simple guidance to help implementers pick between the two main canonicalization mechanisms referred to in this specification, namely JSON Canonicalization Scheme [ RFC8785 ] and RDF Dataset Canonicalization [ RDF-CANON ], from a privacy perspective.
If an application does not require performing a selective disclosure of information in a secured document, nor does it utilize JSON-LD, then JSON Canonicalization Scheme [ RFC8785 ] is an attractive approach.
If an application uses JSON-LD and might require selective disclosure of information in a secured document, then using a cryptography suite that uses RDF Dataset Canonicalization [ RDF-CANON ] is an attractive approach.
Implementers are also advised that other selective disclosure mechanisms that perform no transformations are available, that secure the data by wrapping it in a cryptographic envelope instead of embedding the proof in the data, such as SD-JWTs [ SD-JWT ]. This approach has simplicity advantages in some use cases, at the expense of some of the benefits provided by the approach detailed in this specification.
Since the technology to secure documents described by this specification is generalized in nature, the privacy implications of its use might not be immediately apparent to readers. To understand the sort of privacy concerns one might need to consider in a complete software system, implementers are urged to read about how this technology is used in the verifiable credentials ecosystem [ VC-DATA-MODEL-2.0 ]; see the section on Verifiable Credential Privacy Considerations for more information.
The following section describes accessibility considerations that developers implementing this specification are urged to consider in order to ensure that their software is usable by people with different cognitive, motor, and visual needs. As a general rule, this specification is used by system software and does not directly expose individuals to information subject to accessibility considerations. However, there are instances where individuals might be indirectly exposed to information expressed by this specification and thus the guidance below is provided for those situations.
This specification enables the expression of dates and times related to the validity period of cryptographic proofs. This information might be indirectly exposed to an individual if a proof is processed and is detected to be outside an allowable time range. When exposing these dates and times to an individual, implementers are urged to take into account cultural normas and locales when representing dates and times in display software. In addition to these considerations, presenting time values in a way that eases the cognitive burden on the individual receiving the information is a suggested best practice.
For example, when conveying the expiration date for a particular set of digitally signed information, implementers are urged to present the time of expiration using language that is easier to understand rather than language that optimizes for accuracy. Presenting the expiration time as "This ticket expired three days ago." is preferred over a phrase such as "This ticket expired on July 25th 2023 at 3:43 PM." The former provides a relative time that is easier to comprehend than the latter time, which requires the individual to do the calculation in their head and presumes that they are capable of doing such a calculation.
This section is non-normative.
Sections 2.1.1 Proof Sets and 2.1.2 Proof Chains describe how multiple proofs can be expressed in a secured data document ; that is, instead of a single proof included in the secured data document , one can express multiple proofs in an list as shown in Example 6 and Example 7 . The elements of this list are members of a proof set and, optionally, a proof chain . The purpose of this section is to explain the intended use of each of these features and, in particular, their differing security properties. These differing security properties lead to differences in the processing in section 4.3 Add Proof Set/Chain .
This section represents secured data documents , including their proofs, in an abbreviated manner so that the important security properties can be observed.
Consider a scenario with three signatories: a CEO, a CFO, and a VP of Engineering. Each will need to have a public key and secret key pair for signing a document. We denote the secret/public keys of each of these signatories by secretCEO/publicCEO , secretCFO/publicCFO , and secretVPE/publicVPE , respectively.
When constructing a proof set where each of the signatories signs an inputDocument without concern, we construct a proof symbolically as:
{ "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "created": "2023-03-05T19:23:24Z", "proofPurpose": "assertionMethod", "verificationMethod":publicCEO
, "proofValue": signature(secretCEO
,inputDocument
) }
Where
publicCEO
is
used
as
a
placeholder
for
a
reference
that
resolves
to
the
CEO's
public
key
and
signature(
secretKey
,
inputDocument
)
denotes
the
computation
of
a
digital
signature
by
a
particular
data
integrity
cryptosuite
using
a
particular
secret
key
over
a
particular
document.
The
type
,
cryptosuite
,
created
,
and
proofPurpose
attributes
do
not
factor
into
our
discussion
so
we
will
omit
them.
In
particular,
below
we
show
all
the
proofs
in
a
proof
set
on
a
document
that
has
been
signed
by
the
VP
of
Engineering,
the
CFO,
and
the
CEO:
{ // Remainder of secured data document not shown (above) "proof": [{ "verificationMethod":publicVPE
, "proofValue": signature(secretVPE
,inputDocument
) }, { "verificationMethod":publicCFO
, "proofValue": signature(secretCFO
,inputDocument
) }, { "verificationMethod":publicCEO
, "proofValue": signature(secretCEO
,inputDocument
) }] }
A
holder
or
any
other
intermediary
receiving
a
secured
data
document
containing
a
proof
set
is
able
to
remove
any
of
the
proof
values
within
the
set
prior
to
passing
it
on
to
another
entity
and
the
secured
data
document
will
still
verify.
This
might
or
might
not
have
been
the
intent.
For
the
signatories
sending
a
birthday
card
to
a
valued
employee,
using
a
proof
set
is
probably
fine.
If
we
are
trying
to
model
a
business
process
where
approvals
ascend
the
company
hierarchy,
this
would
not
be
ideal,
since
any
intermediary
could
remove
signatures
from
the
proof
set
and
still
have
it
verify;
for
instance,
in
the
example
below,
it
looks
like
the
CFO
and
CEO
approved
something
without
the
VP
of
Engineering's
concurrence.
{ // Remainder of secured data document not shown (above) "proof": [{ "verificationMethod":publicCFO
, "proofValue": signature(secretCFO
,inputDocument
) }, { "verificationMethod":publicCEO
, "proofValue": signature(secretCEO
,inputDocument
) }] }
It
is
possible
to
introduce
a
dependency
between
proofs
in
a
proof
set
by
setting
the
id
property
of
each
proof
such
that
another
proof
can
reference
it.
In
other
words,
a
dependent
proof
will
be
referenced
by
other
relying
proofs
by
using
the
previousProof
property.
Such
dependency
chains
can
have
arbitrary
depth.
The
intent
of
such
a
proof
chain
is
to
model
an
approval
chain
in
a
business
process
or
a
notary
witnessing
analog
signatures.
The
examples
below
demonstrate
how
a
proof
chain
can
be
constructed
when
the
VP
of
Engineering
signs
off
on
the
document
first;
based
on
the
VP
of
Engineering's
signature
and
a
review,
the
CFO
then
signs
off
on
the
document;
and
finally,
based
on
both
prior
signatures
and
a
review,
the
CEO
signs
off
on
the
document.
Since
others
will
be
referring
to
the
VP
of
Engineering's
signature,
we
need
to
add
an
id
to
the
proof.
First
the
VP
of
Engineering
signs
the
input
document
:
{ // Remainder of secured data document not shown (above) "proof": { "id": "urn:proof-1", "verificationMethod":publicVPE
, "proofValue": signature(secretVPE
,inputDocument
) } }
Next,
the
CFO
receives
the
document,
verifies
that
the
VP
of
Engineering
signed
it,
and
signs
it
based
on
a
review
and
on
the
signature
of
the
VP
of
Engineering.
For
this,
we
need
to
set
up
the
proof
chain
by
indicating
a
dependency
on
the
proof
in
the
document
just
received.
We
do
this
by
setting
the
previousProof
property
of
the
second
proof
to
the
value
urn:proof-1
,
which
"binds"
the
second
proof
to
the
first
proof,
which
is
then
signed.
The
following
example
shows
how
the
dependency
on
the
first
proof
is
created:
{ // Remainder of secured data document not shown (above) "proof": [{ "id": "urn:proof-1", "verificationMethod":publicVPE
, "proofValue": signature(secretVPE
,inputDocument
) }, { "id": "urn:proof-2", "verificationMethod":publicCFO
, "previousProof": "urn:proof-1", "proofValue": signature(secretCFO
,inputDocumentWithProof1
) }] }
Now,
when
the
CEO
verifies
the
received
secured
data
document
with
the
above
proof
chain
,
they
will
check
that
the
CFO
signed
based
on
the
signature
of
the
VP
of
Engineering.
First,
they
will
check
the
proof
with
an
id
property
whose
value
is
urn:proof-1
against
the
public
key
of
the
VP
of
Engineering.
Note
that
this
proof
is
over
the
original
document.
Next,
the
CEO
will
check
the
proof
with
an
id
property
whose
value
is
urn:proof-2
against
the
public
key
of
the
CFO.
However,
to
make
sure
that
the
CFO
signed
the
document
with
proof
that
the
VP
of
Engineering
had
already
signed,
we
verify
this
proof
over
the
combination
of
the
document
and
urn:proof-1
.
If
verification
is
successful,
the
CEO
signs,
producing
a
proof
over
the
document
which
includes
urn:proof-1
and
urn:proof-2
.
The
final
proof
chain
looks
like
this:
{ // Remainder of secured data document not shown (above) "proof": [{ "id": "urn:proof-1", "verificationMethod":publicVPE
, "proofValue": signature(secretVPE
,inputDocument
) }, { "id": "urn:proof-2", "verificationMethod":publicCFO
, "previousProof": "urn:proof-1", "proofValue": signature(secretCFO
,inputDocumentWithProof1
) }, { "id": "urn:proof-3", "verificationMethod":publicCEO
, "previousProof": "urn:proof-2", "proofValue": signature(secretCEO
,inputDocumentWithProof2
) }] }
The recipient of this secured data document then validates it in a similar way, checking each proof in the chain.
This section is non-normative.
This section contains the substantive changes that have been made to this specification over time.
Changes since the First Candidate Recommendation :
created
proof
option
is
not
required
and
additional
proof
options
are
included
in
the
generated
proof.
Changes since the First Public Working Draft :
JsonWebKey
and
Multikey
definitions
and
context
files.
Ed25519Signature2020
and
moved
into
separate
specification.
nonce
and
expires
to
proofs.
revoked
and
expires
to
verification
methods.
domain
property
to
allow
for
an
array
of
values.
cryptosuiteString
type
to
proofs
to
enable
proof
compression.
digestMultibase
property
and
multibase
data
type
for
securing
remote
content,
and
guidance
on
adding
digestMultibase
to
contexts.
dateTimeStamp
.
DataIntegrityProof
objects
need
to
contain
the
cryptosuite
property.
This section is non-normative.
Work on this specification has been supported by the Rebooting the Web of Trust community facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, Brian Weller, Betty Dhamers, Kaliya Young, Manu Sporny, Drummond Reed, Joe Andrieu, Heather Vescent, Kim Hamilton Duffy, Samantha Chase, and Andrew Hughes. The participants in the Internet Identity Workshop, facilitated by Phil Windley, Kaliya Young, Doc Searls, and Heidi Nobantu Saul, also supported the refinement of this work through numerous working sessions designed to educate about, debate on, and improve this specification.
The Working Group also thanks our Chairs, Brent Zundel and Kristina Yasuda, as well as our W3C Staff Contact, Ivan Herman, for their expert management and steady guidance of the group through the W3C standardization process.
Portions of the work on this specification have been funded by the United States Department of Homeland Security's Science and Technology Directorate under contracts 70RSAT20T00000029, 70RSAT21T00000016, 70RSAT23T00000005, 70RSAT20T00000010/P00001, 70RSAT20T00000029, 70RSAT21T00000016/P00001, 70RSAT23T00000005, 70RSAT23C00000030, 70RSAT23R00000006, 70RSAT24T00000011, and the National Science Foundation through NSF 22-572. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.
The Working Group would like to thank the following individuals for reviewing and providing feedback on the specification (in alphabetical order):
Will Abramson, Mahmoud Alkhraishi, Christopher Allen, Joe Andrieu, Bohdan Andriyiv, Anthony, George Aristy, Greg Bernstein, Bob420, Sarven Capadisli, Melvin Carvalho, David Chadwick, Matt Collier, Gabe Cohen, Sebastian Crane, Kyle Den Hartog, Veikko Eeva, Eric Elliott, Raphael Flechtner, Julien Fraichot, Benjamin Goering, Kim Hamilton Duffy, Joseph Heenan, Helge, Ivan Herman, Michael Herman, Anil John, Andrew Jones, Michael B. Jones, Rieks Joosten, Gregory K, Gregg Kellogg, Filip Kolarik, David I. Lehn, Charles E. Lehner, Christine Lemmer-Webber, Eric Lim, Dave Longley, Tobias Looker, Jer Miller, nightpool, Luis Osta, Nate Otto, George J. Padayatti, Addison Phillips, Mike Prorock, Brian Richter, Anders Rundgren, Eugeniu Rusu, Markus Sabadello, silverpill, Wesley Smith, Manu Sporny, Patrick St-Louis, Orie Steele, Henry Story, Oliver Terbu, Ted Thibodeau Jr, John Toohey, Bert Van Nuffelen, Mike Varley, Snorre Lothar von Gohren Edwin, Jeffrey Yasskin, Kristina Yasuda, Benjamin Young, Dmitri Zagidulin, and Brent Zundel.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: