The Security vocabulary is used to enable Internet-based applications to encrypt, decrypt, and digitally sign information expressed as Linked Data. It also provides vocabulary terms for the creation and management of a decentralized Public Key Infrastructure via the Web.
This is an experimental vocabulary and is not intended for use in production systems by non-experts.
This document describes a number of classes and properties that can be used to express digital signatures and achieve cryptographic protection for Linked Data resources. This specification was designed as a modular part of the PaySwarm decentralized payment system for the Web.
This entire document is a work in progress and should be considered in beta until it is ratified as an official document via the World Wide Web Consortium.
This class represents a linked data signature suite. See ecdsa-secp256k1.
{ "type": "EcdsaSecp256k1Signature2019", "created": "2020-03-30T20:54:52Z", "verificationMethod": "did:example:123#qfknmVDhMi3Uc190IHBRfBRqMgbEEBRzWOj1E9EmzwM", "proofPurpose": "assertionMethod", "jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..EsCNG3KD8CcurIBd354JMIYvsBr9bvF17RQbfqEg5dZy45vmSGVg1U5_rlXihjGLb3EtTK9-73X3YYYgfW2Byg" }
This class represents a linked data signature suite. See ecdsasecp256k1recoverysignature2020.
{ "type": "EcdsaSecp256k1RecoverySignature2020", "created": "2020-04-11T21:07:06Z", "verificationMethod": "did:example:123#vm-3", "proofPurpose": "assertionMethod", "jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..pp9eiLCMfN4EfSB3cbl3UxJ4TtgUaTfByDaaB6IZbXsnvIy5AUIFjbgaiFNtq9-3f8mP7foD_HXpjrdWZfzlwAE" }
This class represents a linked data signature verification key. See ecdsa-secp256k1.
{ "id": "did:example:123#WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU", "type": "EcdsaSecp256k1VerificationKey2019", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "4xAbUxbGGFPv4qpHlPFAUJdzteUGR1lRK-CELCufU9w", "y": "EYcgCTsff1qtZjI9_ckZTXDSKAIuM0BknrKgo0BZ_Is", "kty": "EC", "kid": "WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU" } }
This class represents a linked data signature verification key. See ecdsasecp256k1recoverymethod2020.
{ "id": "did:example:123#WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU", "type": "EcdsaSecp256k1RecoveryMethod2020", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "4xAbUxbGGFPv4qpHlPFAUJdzteUGR1lRK-CELCufU9w", "y": "EYcgCTsff1qtZjI9_ckZTXDSKAIuM0BknrKgo0BZ_Is", "kty": "EC", "kid": "WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU" } }
{ "id": "did:example:123#keys-1", "type": "EcdsaSecp256k1RecoveryMethod2020", "controller": "did:example:123", "blockchainAccountId": "eip155:1:0x89a932207c485f85226d86f7cd486a89a24fcc12" }
This class represents a linked data signature suite. See rsa.
{ "type": "RsaSignature2018", "created": "2017-06-18T21:19:10Z", "proofPurpose": "assertionMethod", "verificationMethod": "https://example.edu/issuers/keys/1", "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..TCYt5X sITJX1CxPCT8yAV-TVkIEq_PbChOMqsLfRoPsnsgw5WEuts01mq-pQy7UJiN5mgRxD-WUc X16dUEMGlv50aqzpqh4Qktb3rk-BuQy72IFLOqV0G_zS245-kronKb78cPN25DGlcTwLtj PAYuNzVBAh4vGHSrQyHUdBBPM" }
This class represents a linked data signature verification key. See rsa.
{ "id": "did:example:123456789abcdefghi#keys-1", "type": "RsaVerificationKey2018", "controller": "did:example:123456789abcdefghi", "expires": "2017-02-08T16:02:20Z", "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n" }
This class represents a message digest that may be used for data integrity verification. The digest algorithm used will determine the cryptographic properties of the digest.
The example below describes a cryptographic digest:
{ "@context": "https://w3id.org/security/v1", "@type": "Digest", "digestAlgorithm": "http://www.w3.org/2000/09/xmldsig#sha1", "digestValue": "981ec496092bf6ee18d6255d96069b528633268b" }
A class of messages that are obfuscated in some cryptographic manner. These messages are incredibly difficult to decrypt without the proper decryption key.
The example below expresses a message that has been encrypted using an
AES
cipher in
Galois/Counter Mode and a
128-bit key (AES-128-GCM). The key has been encrypted using an RSA public key.
The encrypted message, cipherData
, and encrypted key,
cipherKey
, are both base64-encoded. To decrypt the message, first
the cipherKey
must be decrypted using the private key associated
with the publicKey
. Then, the cipherData
can be
decrypted using the decrypted cipherKey
,
cipherAlgorithm
, initializationVector
, and
authenticationTag
.
{ "@context": "https://w3id.org/security/v1", "@type": "EncryptedMessage", "cipherData": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩ a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩ UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩ Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩ L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩ Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩ ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩ UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩ bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩ YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==", "cipherKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩ gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩ z7u3IxpqNVcXHExjXQE=", "cipherAlgorithm": "aes-128-gcm", "authenticationTag": "q25H1CzsE731OmeyEle93w==", "initializationVector": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==" "publicKey": "https://example.com/people/john/keys/23" }
A graph signature is used for digital signatures on RDF graphs. The default canonicalization mechanism is specified in the RDF Graph normalization specification, which effectively deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and RSA to perform the digital signature.
The example below shows how a basic JSON-LD signature is expressed in a JSON-LD snippet. Note that the signature property is directly embedded in the object. The signature algorithm specifies how a signature can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "signature": { "@type": "GraphSignature2012", "creator": "http://manu.sporny.org/keys/5", "signatureValue": "OGQzNGVkMzVmMmQ3ODIyOWM32MzQzNmExMgoYzI4ZDY3NjI4NTIyZTk=" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which effectively deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and RSA to perform the digital signature. This signature uses a algorithm for producing the data that it signs and verifies that is different from other Linked Data signatures.
The example below shows how a basic JSON-LD signature is expressed in a JSON-LD snippet. Note that the signature property is directly embedded in the object. The signature algorithm specifies how the signature can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "signature": { "@type": "LinkedDataSignature2015", "creator": "http://manu.sporny.org/keys/5", "created": "2015-09-23T20:21:34Z", "signatureValue": "OGQzNGVkMzVmMmQ3ODIyOWM32MzQzNmExMgoYzI4ZDY3NjI4NTIyZTk=" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which effectively deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and RSA to perform the digital signature.
The example below shows how a basic JSON-LD signature is expressed in a JSON-LD snippet. Note that the signature property is directly embedded in the object. The signature algorithm specifies how the signature can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Dave Longley", "homepage": "https://w3id.org/people/dave", "signature": { "@type": "LinkedDataSignature2016", "creator": "https://w3id.org/people/dave/keys/2", "created": "2016-11-05T03:12:54Z", "signatureValue": "OGQzNGVkMzVmMmQ3ODIyOWM32MzQzNmExMgoYzI4ZDY3NjI4NTIyZTk=" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which effectively deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and ECDSA to perform the digital signature. More information at https://w3c-ccg.github.io/lds-merkle-proof-2019/
The example below shows how a basic JSON-LD signature is expressed in a JSON-LD snippet. Note that the proof property is directly embedded in the object. The signature algorithm specifies how the signature can be generated and verified.
{ "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3id.org/blockcerts/v3.0-alpha", "https://www.w3.org/2018/credentials/examples/v1" ], "id": "urn:uuid:bbba8553-8ec1-445f-82c9-a57251dd731c", "type": [ "VerifiableCredential", "BlockcertsCredential" ], "issuer": "did:example:23adb1f712ebc6f1c276eba4dfa", "issuanceDate": "2010-01-01T19:33:24Z", "credentialSubject": { "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "alumniOf": { "id": "did:example:c276e12ec21ebfeb1f712ebc6f1" } }, "proof": { "type": "MerkleProof2019", "created": "2020-11-03T14:13:42.808099Z", "proofValue": "zMcm4LfQFUZkWZyLpVrzYzaHRssD3xGQ6Yh6nEhErjfAqnxDWo7gBawdhynnbiucoqqwye54oTs5p6frH385nVvBf2UXMgRVtBZLq6tHN1MY1hQBMBBtXbWbYzj99GotAJRs7PxcvQmUQKHs8hkokZhgw92CNAtvDn2jeycvuyFPtWorxZaGP23mDkgwpberKmAqcPcsUFNooGe1UkQj8wws8D9paKHwFWxyCMvXNuYUGaBdZDaSpcd7uv3kEwgZAzAHb1jMgDeLSN1EdZA33LhPj5ACxMKs3vmwpTnjpNiALoZpJan", "proofPurpose": "assertionMethod", "verificationMethod": "did:example:23adb1f712ebc6f1c276eba4dfa#key-1" } }
This class represents a verification key.
{ "id": "did:example:123#z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F", "type": "X25519KeyAgreementKey2019", "controller": "did:example:123", "publicKeyBase58": "96XGGce9y12gRTxEcnuvpP8tCZzE39WkpKHvUZ6DLg6d" }
This class represents a linked data signature verification key. See eddsa-ed25519.
{ "id": "did:example:123#z6MkkQBvgvqb6zGvS4cydworpUaRDzpszSFixq49ahbDeUTG", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "6wvt6gb9mSnTKZnGxNr1yP2RQRZ2aZ1NGp9DkRdCjFft" }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and JWS to perform the digital signature.
The JWS used with Linked Data Signatures is the detached and unencoded payload variant. See the links below for details:
The example below shows how a basic JSON-LD proof is expressed in a JSON-LD snippet. Note that the proof property is directly embedded in the object. The signature algorithm specifies how the proof can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Dave Longley", "homepage": "https://w3id.org/people/dave", "proof": { "type": "Ed25519Signature2018", "verificationMethod": "https://w3id.org/people/dave/keys/2", "created": "2016-11-05T03:12:54Z", "proofPurpose": "assertionMethod", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..dXNHwJ-9iPMRQ4AUcv9j-7LuImTiWAG0sDYbRRDDiyAjOV9CUmjLMKiePpytoAmGNGNTHDlEOsTa4CS3dZ7yBg" } }
A linked data proof suite verification method type
used with Ed25519Signature2020
.
This suite is unstable and subject to change.
A linked data proof suite proof type
used with the verification method type Ed25519VerificationKey2020
.
This suite is unstable and subject to change.
A linked data proof suite verification method type
used with JsonWebSignature2020
.
This suite is unstable and subject to change.
See also: w3c-ccg/lds-jws2020.
{ "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A", "type": "JsonWebKey2020", "controller": "did:example:123", "publicKeyJwk": { "kty": "OKP", "crv": "Ed25519", "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which deterministically names all unnamed nodes. The default signature mechanism uses a SHA-256 digest and JWS to perform the digital signature.
This suite is unstable and subject to change.
See also: w3c-ccg/lds-jws2020.
The JWS used with Linked Data Signatures is the detached and unencoded payload variant. See the links below for details:
The example below shows how a basic JSON-LD proof is expressed in a JSON-LD snippet. Note that the proof property is directly embedded in the object. The signature algorithm specifies how the proof can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Dave Longley", "homepage": "https://w3id.org/people/dave", "proof": { "type": "JsonWebSignature2020", "verificationMethod": "https://w3id.org/people/dave/keys/2", "created": "2016-11-05T03:12:54Z", "proofPurpose": "assertionMethod", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..dXNHwJ-9iPMRQ4AUcv9j-7LuImTiWAG0sDYbRRDDiyAjOV9CUmjLMKiePpytoAmGNGNTHDlEOsTa4CS3dZ7yBg" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which deterministically names all unnamed nodes. Importantly, a BbsBlsSignature digests each of the statements produced by the normalization process individually to enable selective disclosure. The signature mechanism uses Blake2B as the digest for each statement and produces a single output digital signature.
A Bbs signature is a cryptographic digital signature that works with any pairing friendly elliptic curve, a BbsBls signature is a BBS signature using keys from the BLS12-381 curve:
The example below shows how a basic JSON-LD proof is expressed in a JSON-LD snippet. Note that the proof property is directly embedded in the object. The signature algorithm specifies how the proof can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Dave Longley", "homepage": "https://w3id.org/people/dave", "proof": { "type": "BbsBlsSignature2020", "verificationMethod": "https://w3id.org/people/dave/keys/2", "created": "2016-11-05T03:12:54Z", "proofPurpose": "assertionMethod", "proofValue": "pTy8PJCw93RrD+X55McbjHfrlW5SJYNhF84Eggafnlb2CH8QtfXfNsTnVuTQp8UfKKbKqOp6ASwv2kmKtXJJpK+n7+mNKMbeBqw/fuwbu5w/QjvCgYZH3WhlZq6zTmRN9MwO1lQOxntcnKP8xmaoAw==" } }
A Linked Data signature is used for digital signatures on RDF Datasets. The default canonicalization mechanism is specified in the RDF Dataset Normalization specification, which deterministically names all unnamed nodes. Importantly, a BbsBlsSignatureProof2020 is in fact a proof of knowledge of an unrevealed BbsBlsSignature2020 enabling the ability to selectively reveal information from the set that was originally signed. Each of the statements produced by the normalizing process for a JSON-LD document featuring a "BbsBlsSignatureProof2020" represent statements that were originally signed in producing the BbsBlsSignature2020 and represent the denomination under which information can be selectively disclosed. The signature mechanism uses Blake2B as the digest for each statement and produces a single output digital signature.
A Bbs signature proof is a cryptographic digital proof of knowledge derived from a Bbs signature that works with any pairing friendly elliptic curve, a BbsBls signature proof is one that uses keys from the BLS12-381 curve:
The example below shows how a basic JSON-LD proof is expressed in a JSON-LD snippet. Note that the proof property is directly embedded in the object. The signature algorithm specifies how the proof can be generated and verified.
{ "@context": ["https://w3id.org/security/v1", "http://json-ld.org/contexts/person.jsonld"] "@type": "Person", "name": "Dave Longley", "homepage": "https://w3id.org/people/dave", "proof": { "type": "BbsBlsSignature2020", "verificationMethod": "https://w3id.org/people/dave/keys/2", "created": "2016-11-05T03:12:54Z", "proofPurpose": "assertionMethod", "proofValue": "AAoD/4XIHpCb/4necmgnauMPaGKoQiTfDmB3Gk+oX99V8qe/Os3X21NNnPrr5QusW1eizom+c5zIMi8uIprRuumLCpN/HpzbTYaYrts+R6wIoB9GtUOcBR3Pwp6avuPK1sO84YStE91pLu5zO64/OsHz2XsqMb3Qo3AL9drfwlhCOh+gzVuEkHtS38TxLvhru/I7BwAAAHSFWEOFEHY4bXwZZf8710RdkN2phd0A3DIi4fq+NMh0Bxx9vmBevt7LnaVln5so20UAAAACOkUnNGzLNxtWPYhS4hiVFf2D3mkQ2LaxaYsjz7Dvc8gz6ucnMMMYFGEsN4DwgrAk3BekfAb40RrzXPRWRWni3LXi4kbGx6BNlWB28L7LKrBBsgi64xALHEWXedU9mxCrz5fENJ3G45cx6Yh7ixHxMQAAAAJhQb1RFEBF0X1bggECt4ipbWwvKLuSECtJ5LmTcDDF4DinW96UfoR3ZZ3F3BR2km+uDWOi1dCT8t/aCmnIPUkM" } }
This class represents a linked data signature key. See eddsa-ed25519.
{ "id": "did:example:489398593#test", "type": "Bls12381G1Key2020", "controller": "did:example:489398593", "publicKeyBase58": "4N9Kg9BxmDXtf2QgRH2j1UfFAcQAmgu9Xpwe2fLbSNQHPQHBK5dHrQfFvexvux" }
This class represents a linked data signature key. See eddsa-ed25519.
{ "id": "did:example:489398593#test", "type": "Bls12381G2Key2020", "controller": "did:example:489398593", "publicKeyBase58": "oqpWYKaZD9M1Kbe94BVXpr8WTdFBNZyKv48cziTiQUeuhm7sBhCABMyYG4kcMrseC68YTFFgyhiNeBKjzdKk9MiRWuLv5H4FFujQsQK2KTAtzU8qTBiZqBHMmnLF4PL7Ytu" }
This class represents a cryptographic key that may be used for encryption, decryption, or digitally signing data.
The example below describes a cryptographic key that contains both the public and private key as well as the controller of the key. The controller property is described in the Commerce Vocabulary.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "controller": "https://payswarm.example.com/i/bob", "privateKeyPem": "-----BEGIN PRIVATE KEY-----\nMIIBG0BA...OClDQAB\n-----END PRIVATE KEY-----\n", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
This class represents a digital signature on serialized data. It is an abstract class and should not be used other than for Semantic Web reasoning purposes, such as by a reasoning agent.
A Signature class MUST NOT be used as an RDF type. It should instead be used as the base class for all signature classes. A signature sub-class SHOULD express at least three signature algorithm properties: canonicalizationAlgorithm, digestAlgorithm, and signatureAlgorithm.
The cipher algorithm describes the mechanism used to encrypt a message. It is typically a string expressing the cipher suite, the strength of the cipher, and a block cipher mode.
The example below expresses a message that has been encrypted using an
AES
cipher in
Galois/Counter Mode and a
128-bit key (AES-128 GCM). The key has been encrypted using an RSA public key.
The encrypted message, cipherData
, and encrypted key,
cipherKey
are both base64-encoded. To decrypt the message, first
the cipherKey
must be decrypted using the private key associated
with the publicKey
. Then, the cipherData
can be
decrypted using the decrypted cipherKey
,
cipherAlgorithm
, initializationVector
, and
authenticationTag
.
{ "@context": "https://w3id.org/security/v1", "@type": "EncryptedMessage", "cipherData": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩ a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩ UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩ Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩ L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩ Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩ ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩ UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩ bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩ YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==", "cipherKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩ gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩ z7u3IxpqNVcXHExjXQE=", "cipherAlgorithm": "aes-128-gcm", "authenticationTag": "q25H1CzsE731OmeyEle93w==", "initializationVector": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==" "publicKey": "https://example.com/people/john/keys/23" }
Cipher data an opaque blob of information that is used to specify an encrypted message.
cipherData
, and encrypted key,
cipherKey
are both base64-encoded. To decrypt the message, first
the cipherKey
must be decrypted using the private key associated
with the publicKey
. Then, the cipherData
can be
decrypted using the decrypted cipherKey
,
cipherAlgorithm
, initializationVector
, and
authenticationTag
.
{ "@context": "https://w3id.org/security/v1", "@type": "EncryptedMessage", "cipherData": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩ a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩ UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩ Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩ L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩ Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩ ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩ UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩ bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩ YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==", "cipherKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩ gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩ z7u3IxpqNVcXHExjXQE=", "cipherAlgorithm": "aes-128-gcm", "authenticationTag": "q25H1CzsE731OmeyEle93w==", "initializationVector": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==" "publicKey": "https://example.com/people/john/keys/23" }
The digest algorithm is used to specify the cryptographic function to use when generating the data to be digitally signed. Typically, data that is to be signed goes through three steps: 1) canonicalization, 2) digest, and 3) signature. This property is used to specify the algorithm that should be used for step #2. A signature class typically specifies a default digest method, so this property is typically used to specify information for a signature algorithm.
The following example shows how the digest algorithm can be specified for a particular signature type:
{ "@context": "https://w3id.org/security/v1", "@id": "https://w3id.org/security#GraphSignature2012", "@type": "Signature", "canonicalizationAlgorithm": "https://w3id.org/jsonld#UGNA2012", "digestAlgorithm": "http://example.com/digests#sha512", "signatureAlgorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1", }
The digest value is used to express the output of the digest algorithm expressed in Base-16 (hexadecimal) format.
The following example shows how the output of the digest algorithm can be encoded in JSON-LD:
{ "@context": [ "https://w3id.org/security/v1", { "dc": "https://w3id.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/" } ], "@id": "http://example.com/logo.jpg", "@type": "foaf:Image", "dc:title": "Example Logo", "digest": { "@type": "Digest", "digestAlgorithm": "http://www.w3.org/2000/09/xmldsig#sha1", "digestValue": "981ec496092bf6ea18d6251d36068b52b633268b" } }
A cipher key is a symmetric key that is used to encrypt or decrypt a piece of information. The key itself may be expressed in clear text or encrypted.
The example below expresses a message that has been encrypted using an
AES
cipher in
Galois/Counter Mode and a
128-bit key (AES-128 GCM). The key has been encrypted using an RSA public key.
The encrypted message, cipherData
, and encrypted key,
cipherKey
are both base64-encoded. To decrypt the message, first
the cipherKey
must be decrypted using the private key associated
with the publicKey
. Then, the cipherData
can be
decrypted using the decrypted cipherKey
,
cipherAlgorithm
, initializationVector
, and
authenticationTag
.
{ "@context": "https://w3id.org/security/v1", "@type": "EncryptedMessage", "cipherData": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩ a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩ UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩ Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩ L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩ Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩ ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩ UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩ bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩ YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==", "cipherKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩ gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩ z7u3IxpqNVcXHExjXQE=", "cipherAlgorithm": "aes-128-gcm", "authenticationTag": "q25H1CzsE731OmeyEle93w==", "initializationVector": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==" "publicKey": "https://example.com/people/john/keys/23" }
A blockchainAccountId
property is used to specify a blockchain account identifier, as per the
CAIP-10 Account ID Specification.
The following example demonstrates the expression of a Mainnet Ethereum address.
{ "id": "did:example:123#blockchainAccountId", "type": "EcdsaSecp256k1RecoverySignature2020", "blockchainAccountId":"eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb" }
The following example demonstrates the expression of a Mainnet Bitcoin address.
{ "id": "did:example:123#blockchainAccountId", "type": "EcdsaSecp256k1RecoverySignature2020", "blockchainAccountId":"bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6" }
The following example demonstrates the expression of a Cosmos address.
{ "id": "did:example:123#blockchainAccountId", "type": "EcdsaSecp256k1RecoverySignature2020", "blockchainAccountId":"cosmos:cosmos:1t2uflqwqe0fsj0shcfkrvpukewcw40yjj6hdc0" }
An ethereumAddress
property is used to specify the Ethereum address (as per the
Ethereum Yellow Paper: ETHEREUM: A SECURE DECENTRALISED
GENERALISED TRANSACTION LEDGER composed of the prefix "0x", a common identifier for hexadecimal, concatenated
with the rightmost 20 bytes of the Keccak-256 hash (big endian) of the ECDSA public key (the curve used is the
so-called secp256k1). In hexadecimal, 2 digits represent a byte, meaning addresses contain 40 hexadecimal digits.
The Ethereum address should also contain a checksum as per EIP-55
The following example demonstrates the expression of an Ethereum address in hex format.
{ "id": "did:example:123#ethereumAddress", "type": "EcdsaSecp256k1RecoverySignature2020", "ethereumAddress":"0xb794f5ea0ba39494ce839613fffba74279579268" }
The expiration time is typically associated with a Key and specifies when the validity of the key will expire. It is considered a best practice to only create keys that have very definite expiration periods. This period is typically set to between six months and two years. An digital signature created using an expired key MUST be marked as invalid by any software attempting to verify the signature.
The following example shows a key that was created on January 3rd 2012 and that expires on January 3rd 2014:
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "created": "2012-01-03T14:34:57+0000", "expires": "2014-01-03T14:34:57+0000", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
The initialization vector (IV) is a byte stream that is typically used to initialize certain block cipher encryption schemes. For a receiving application to be able to decrypt a message, it must know the decryption key and the initialization vector. The value is typically base-64 encoded.
The example below expresses a message that has been encrypted using an
AES
cipher in
Galois/Counter Mode and a
128-bit key (AES-128 GCM). The key has been encrypted using an RSA public key.
The encrypted message, cipherData
, and encrypted key,
cipherKey
are both base64-encoded. To decrypt the message, first
the cipherKey
must be decrypted using the private key associated
with the publicKey
. Then, the cipherData
can be
decrypted using the decrypted cipherKey
,
cipherAlgorithm
, initializationVector
, and
authenticationTag
.
{ "@context": "https://w3id.org/security/v1", "@type": "EncryptedMessage", "cipherData": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩ a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩ UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩ Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩ L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩ Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩ ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩ UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩ bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩ YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==", "cipherKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩ gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩ z7u3IxpqNVcXHExjXQE=", "cipherAlgorithm": "aes-128-gcm", "authenticationTag": "q25H1CzsE731OmeyEle93w==", "initializationVector": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==" "publicKey": "https://example.com/people/john/keys/23" }
This property is used in conjunction with the input to the signature hashing function in order to protect against replay attacks. Typically, receivers need to track all nonce values used within a certain time period in order to ensure that an attacker cannot merely re-send a compromised packet in order to execute a privileged request.
The following example shows a fairly sensitive request that is digitally signed with a nonce. How the nonce is used is up to the signature algorithm, but the value is typically included as input to the signature hashing function in order to protect against replay attacks.
{ "@context": [ "https://w3id.org/security/v1", { "ex": "http://example.org/vocab#" } ], "@graph": { "ex:request": "DELETE /private/2840-credit-card-log" }, "signature": { "@type": "GraphSignature2012", "creator": "http://example.com/people/john-doe#key-5", "nonce": "8495723045.84957", "signatureValue": "Q3ODIyOGQzNGVkMzVm4NTIyZ43OWM32NjITkZDYMmMzQzNmExMgoYzI=" } }
The canonicalization algorithm is used to transform the input data into a form that can be passed to a cryptographic digest method. The digest is then digitally signed using a digital signature algorithm. Canonicalization ensures that a piece of software that is generating a digital signature is able to do so on the same set of information in a deterministic manner.
The example below shows the establishment of a new signature class, using the three pieces of information that are typically required for a signature - the canonicalization algorithm, the digest algorithm and the signature algorithm:
{ "@context": "https://w3id.org/security/v1", "@id": "https://w3id.org/security#GraphSignature2012", "@type": "Signature", "canonicalizationAlgorithm": "https://w3id.org/jsonld#UGNA2012", "digestAlgorithm": "http://example.com/digests#sha512", "signatureAlgorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1", }
A controller is an entity that claims control over a particular resource. Note that control is best validated as a two-way relationship where the controller claims control over a particular resource, and the resource clearly identifies its controller.
The example below shows a cryptographic key that is owned by an entity identified by a URL. Presumably, this key is under the control of the controller and can be used to infer that any digitally signed content using the key was signed by a software agent of the controller:
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
The `owner` property is deprecated. New cryptography suite creators and developers are advised to use the `controller` property for encoding public key parameters.
An owner is an entity that claims control over a particular resource. Note that ownership is best validated as a two-way relationship where the owner claims ownership over a particular resource, and the resource clearly identifies its owner.
The example below shows a cryptographic key that is owned by an entity identified by a URL. Presumably, this key is under the control of the owner and can be used to infer that any digitally signed content using the key was signed by a software agent of the owner:
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "owner": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
A secret that is used to generate a key that can be used to encrypt or decrypt message. It is typically a string value.
A private key PEM property is used to specify the PEM-encoded version of the private key. This encoding is compatible with almost every Secure Sockets Layer library implementation and typically plugs directly into functions intializing private keys.
The following example demonstrates the expression of a private key in PEM format. The elipsis ("...") in the middle of the string denotes more data that has been abbreviated for the sake of the readability of the example.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "controller": "https://payswarm.example.com/i/bob", "privateKeyPem": "-----BEGIN PRIVATE KEY-----\nMIIBG0BA...OClDQAB\n-----END PRIVATE KEY-----\n" }
A verificationMethod property is used to specify a URL that contains information used for proof verification.
The following example demonstrates the expression of a public key verificationMethod belonging
to the identity https://payswarm.example.com/i/bob
.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
A public key property is used to specify a URL that contains information about a public key.
The following example demonstrates the expression of a public key belonging
to the identity https://payswarm.example.com/i/bob
.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
An assertionMethod property is used to specify a URL that contains information about a verificationMethod used for assertions.
The following example demonstrates the expression of a verificationMethod used for assertions belonging
to the identity did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q
.
{ ... "publicKey": [{ "id": "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q", "type": "EcdsaSecp256k1VerificationKey2019", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "NtngWpJUr-rlNNbs0u-Aa8e16OwSJu6UiFf0Rdo1oJ4", "y": "qN1jKupJlFsPFc1UkWinqljv4YE0mq_Ickwnjgasvmo", "kty": "EC", "kid": "WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" } }], "assertionMethod": [{ "id": "did:example:123#z6MkpzW2izkFjNwMBwwvKqmELaQcH8t54QL5xmBdJg9Xh1y4", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "BYEz8kVpPqSt5T7DeGoPVUrcTZcDeX5jGkGhUQBWmoBg" }, "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" ] }
An authentication property is used to specify a URL that contains information about a verificationMethod used for authentication.
The following example demonstrates the expression of a verificationMethod used for authentication belonging
to the identity did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q
.
{ ... "publicKey": [{ "id": "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q", "type": "EcdsaSecp256k1VerificationKey2019", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "NtngWpJUr-rlNNbs0u-Aa8e16OwSJu6UiFf0Rdo1oJ4", "y": "qN1jKupJlFsPFc1UkWinqljv4YE0mq_Ickwnjgasvmo", "kty": "EC", "kid": "WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" } }], "authentication": [{ "id": "did:example:123#z6MkpzW2izkFjNwMBwwvKqmELaQcH8t54QL5xmBdJg9Xh1y4", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "BYEz8kVpPqSt5T7DeGoPVUrcTZcDeX5jGkGhUQBWmoBg" }, "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" ] }
A capabilityDelegation property is used to express that one or more verificationMethods are authorized to verify cryptographic proofs that were created for the purpose of delegating capabilities.
A verificationMethod may be referenced by its identifier (a URL) or expressed in full.
The aforementioned proofs are created to prove that some entity is delegating the authority to take some action to another entity. A verifier of the proof should expect the proof to express a proofPurpose of capabilityDelegation and reference a verificationMethod to verify it. The dereferenced verificationMethod MUST have a controller property that has a property of capabilityDelegation that references the verificationMethod. This indicates that the controller has authorized it for the expressed proofPurpose.
How capabilities are expressed is application-specific.
The following example demonstrates the expression of a verificationMethod used for capability delegation belonging
to the identity did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q
.
{ ... "publicKey": [{ "id": "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q", "type": "EcdsaSecp256k1VerificationKey2019", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "NtngWpJUr-rlNNbs0u-Aa8e16OwSJu6UiFf0Rdo1oJ4", "y": "qN1jKupJlFsPFc1UkWinqljv4YE0mq_Ickwnjgasvmo", "kty": "EC", "kid": "WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" } }], "capabilityDelegation": [{ "id": "did:example:123#z6MkpzW2izkFjNwMBwwvKqmELaQcH8t54QL5xmBdJg9Xh1y4", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "BYEz8kVpPqSt5T7DeGoPVUrcTZcDeX5jGkGhUQBWmoBg" }, "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" ] }
A capabilityInvocation property is used to express that one or more verificationMethods are authorized to verify cryptographic proofs that were created for the purpose of invoking capabilities.
A verificationMethod MAY be referenced by its identifier (a URL) or expressed in full.
The aforementioned proofs are created to prove that some entity is attempting to exercise some authority they possess to take an action. A verifier of the proof should expect the proof to express a proofPurpose of capabilityInvocation and reference a verificationMethod to verify it. The dereferenced verificationMethod MUST have a controller property that, when dereferenced, has a property of capabilityInvocation that references the verificationMethod. This indicates that the controller has authorized it for the expressed proofPurpose.
How capabilities are expressed is application-specific.
The following example demonstrates the expression of a verificationMethod used for capability invocation belonging
to the identity did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q
.
{ ... "publicKey": [{ "id": "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q", "type": "EcdsaSecp256k1VerificationKey2019", "controller": "did:example:123", "publicKeyJwk": { "crv": "secp256k1", "x": "NtngWpJUr-rlNNbs0u-Aa8e16OwSJu6UiFf0Rdo1oJ4", "y": "qN1jKupJlFsPFc1UkWinqljv4YE0mq_Ickwnjgasvmo", "kty": "EC", "kid": "WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" } }], "capabilityInvocation": [{ "id": "did:example:123#z6MkpzW2izkFjNwMBwwvKqmELaQcH8t54QL5xmBdJg9Xh1y4", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "BYEz8kVpPqSt5T7DeGoPVUrcTZcDeX5jGkGhUQBWmoBg" }, "did:example:123#WjKgJV7VRw3hmgU6--4v15c0Aewbcvat1BsRFTIqa5Q" ] }
An keyAgreement property is used to specify a URL that contains information about a verificationMethod used for key agreement.
The following example demonstrates the expression of a verificationMethod used for key agreement belonging
to the identity did:example:123#zC9ByQ8aJs8vrNXyDhPHHNNMSHPcaSgNpjjsBYpMMjsTdS
.
{ ... "keyAgreement": [ { "id": "did:example:123#zC9ByQ8aJs8vrNXyDhPHHNNMSHPcaSgNpjjsBYpMMjsTdS", "type": "X25519KeyAgreementKey2019", "controller": "did:example:123", "publicKeyBase58": "9hFgmPVfmBZwRvFEyniQDBkz9LmV7gDEqytWyGZLmDXE" } ] }
The `publicKeyBase58` property is deprecated. New cryptography suite creators and developers are advised to use the `publicKeyMultibase` property for encoding public key parameters.
A public key Base58 property is used to specify the base58-encoded version of the public key.
The following example demonstrates the expression of a public key in base58 format.
{ "id": "did:example:123#ZC2jXTO6t4R501bfCXv3RxarZyUbdP2w_psLwMuY6ec", "type": "Ed25519VerificationKey2018", "controller": "did:example:123", "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" }
See IANA JOSE. See also RFC 7517.
{ "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A", "type": "JsonWebKey2020", "controller": "did:example:123", "publicKeyJwk": { "crv": "Ed25519", "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ", "kty": "OKP", "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A" } }
A public key PEM property is used to specify the PEM-encoded version of the public key. This encoding is compatible with almost every Secure Sockets Layer library implementation and typically plugs directly into functions intializing public keys.
The following example demonstrates the expression of a public key in PEM format. The elipsis ("...") in the middle of the string denotes more data that has been abbreviated for the sake of the readability of the example.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
The `publicKeyHex` property is deprecated. New cryptography suite creators and developers are advised to use the `publicKeyMultibase` property for encoding public key parameters.
A publicKeyHex
property is used to specify the hex-encoded version of the public key, based on section 8 of rfc4648. Hex encoding is also known as Base16 encoding.
The following example demonstrates the expression of a public key in hex format.
{ "id": "did:example:123#hexKey", "controller": "did:example:123", "type": "EcdsaSecp256k1RecoveryMethod2020", "publicKeyHex":"027560AF3387D375E3342A6968179EF3C6D04F5D33B2B611CF326D4708BADD7770" }
The public key multibase [[MULTIBASE]] property is used to specify the multibase-encoded version of a public key. The contents of the property are defined by specifications such as [[ED25519-2020]] and listed in the Linked Data Cryptosuite Registry [[LD-CRYPTOSUITE-REGISTRY]]. Most public key type definitions are expected to:
The following example demonstrates the expression of a public key in multibase format.
{ "id": "did:example:123#zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", "type": "Ed25519VerificationKey2020", "controller": "did:example:123", "publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" }
The publicKeyService property is used to express the REST URL that provides public key management services.
The following example shows how a website can publish the location of a
public keys service via the .well-known file. The publicKeyService can be found
at the https://payswarm.example.com/public-keys
URL.
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/.well-known/services", "publicKeyService": "https://payswarm.example.com/public-keys" }
The revocation time is typically associated with a Key that has been marked as invalid as of the date and time associated with the property. Key revocations are often used when a key is compromised, such as the theft of the private key, or during the course of best-practice key rotation schedules.
The following example shows a key that was created on January 3rd 2012 and revoked on May 5th 2012:
{ "@context": "https://w3id.org/security/v1", "@id": "https://payswarm.example.com/i/bob/keys/1", "@type": "Key", "created": "2012-01-03T14:34:57+0000", "revoked": "2012-05-01T18:11:19+0000", "controller": "https://payswarm.example.com/i/bob", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMII8YbF3s8q3c...j8Fk88FsRa3K\n-----END PUBLIC KEY-----\n" }
The proof property is used to associate a proof with a graph of information. The proof property is typically not included in the canonicalized graph that is then digested, and digitally signed.
The following example demonstrates how a proof on the graph identified by
the subject http://example.com/people#jane
is expressed using
a JSON-LD proof:
{ "@context": [ "https://w3id.org/security/v1", { "foaf": "http://xmlns.com/foaf/0.1/" } ] "@graph": { "@id": "http://example.com/people#jane", "@type": "foaf:Person", "foaf:name": "Jane Doe", "foaf:homepage": "http://example.org/jane" }, "proof": { "type": "Ed25519Signature2018", "created": "2020-04-03T18:03:33Z", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ktzmVCTovhKWKxnMwDtMnmpUAUF1n7sqbdNmOV0TkxCTb2eHATO6iP7wqjyl_CMehHKnqgW6t9SW4q9TdbCxAg", "proofPurpose": "assertionMethod", "verificationMethod": "did:key:z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y#z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y" } }
The jws property is used to associate a Detached Json Web Signature with a proof.
The following example demonstrates how a proof expressed using a JSON-LD proof with detached jws:
{ ... "proof": { "type": "Ed25519Signature2018", "created": "2020-04-03T18:03:33Z", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ktzmVCTovhKWKxnMwDtMnmpUAUF1n7sqbdNmOV0TkxCTb2eHATO6iP7wqjyl_CMehHKnqgW6t9SW4q9TdbCxAg", "proofPurpose": "assertionMethod", "verificationMethod": "did:key:z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y#z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y" } }
The proofPurpose property is used to associate a purpose, such as assertionMethod
or authentication
with a proof.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with assertionMethod
:
{ ... "proof": { "type": "Ed25519Signature2018", "created": "2020-04-03T18:03:33Z", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ktzmVCTovhKWKxnMwDtMnmpUAUF1n7sqbdNmOV0TkxCTb2eHATO6iP7wqjyl_CMehHKnqgW6t9SW4q9TdbCxAg", "proofPurpose": "assertionMethod", "verificationMethod": "did:key:z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y#z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y" } }
The challenge property is used to associate a challenge with a proof, for use with a proofPurpose such as authentication
.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with purpose authentication
and challenge
:
{ "@context": "https://www.w3.org/2018/credentials/v1", "type": "VerifiablePresentation", "holder": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proof": { "type": "Ed25519Signature2018", "created": "2020-04-02T18:21:44Z", "verificationMethod": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd#z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proofPurpose": "authentication", "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a", "domain": "issuer.interop.transmute.world", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2xjpkHW6EY-cKD8DrMIkkiB2Q_k6kHynTbR7XGgtYR92blQWpL6Q-2nTdQi1rNhJtmHw1wWWssKMO0EdIEnsCw" } }
The domain property is used to associate a domain with a proof, for use with a proofPurpose such as authentication
.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with purpose authentication
and domain
:
{ "@context": "https://www.w3.org/2018/credentials/v1", "type": "VerifiablePresentation", "holder": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proof": { "type": "Ed25519Signature2018", "created": "2020-04-02T18:21:44Z", "verificationMethod": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd#z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proofPurpose": "authentication", "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a", "domain": "issuer.interop.transmute.world", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2xjpkHW6EY-cKD8DrMIkkiB2Q_k6kHynTbR7XGgtYR92blQWpL6Q-2nTdQi1rNhJtmHw1wWWssKMO0EdIEnsCw" } }
The expirationDate property is used to associate an expirationDate with a proof.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with purpose authentication
and expirationDate
:
{ "@context": "https://www.w3.org/2018/credentials/v1", "type": "VerifiablePresentation", "holder": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proof": { "type": "Ed25519Signature2018", "created": "2020-04-02T18:21:44Z", "verificationMethod": "did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd#z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd", "proofPurpose": "authentication", "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a", "expirationDate": "2020-05-02T18:21:44Z", "domain": "issuer.interop.transmute.world", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2xjpkHW6EY-cKD8DrMIkkiB2Q_k6kHynTbR7XGgtYR92blQWpL6Q-2nTdQi1rNhJtmHw1wWWssKMO0EdIEnsCw" } }
The proofValue property is used to associate a proof value with a proof.
The following example demonstrates how a proof is expressed using a JSON-LD proofValue:
{ ... "proof": { "type": "MerkleProof2019", "creator": "did:example:abcdefghij0123456789", "created": "2017-09-23T20:21:34Z", "domain": "example.org", "nonce": "2bbgh3dgjg2302d-d2b3gi423d42", "proofValue": "z76WGJzY2rXtSiZ8BDwU4VgcLqcMEm2dXdgVVS1QCZQUptZ5P8n5YCcnbuMUASYhVNihae7m8VeYvfViYf2KqTMVEH1BKNF6Xc5S2kPpBwsNos6egnrmDMxhtQppZjb47Mi2xG89jZm654uZUatDvfTCoDWuethfRHPSk81qn6od9zGxBxxAYyUPnY9Fs9QEQETm53AN9uk6erSAhJ2R3K8rosrBkSZbVhbzUJTPg22wpddVY8Xu3vhRVNpzyUvCEedg5EM6i7wE4G1CYsz7tbaApEF9aFRB92v4DoiY5GXGjwH5PhhGstJB9ySh9FyDfSYN8qRVVR7i5No2eBi3AjQ7cqaBiWkoSrCoQK7jJ4PyFsu3ZaAuUx8LAtkhaChmwfxH8E25LcTENJhFxqVnPd7f7Q3cUrFciYRqmg8eJsy1AahqbzJQ63n9RtekmwzqnMYrTwft6cLJJGeTSSxCCJ6HKnRtwE7jjDh6sB2ZeVj494VppdAVJBz2AAiZY9BBnCD8wUVgwqH3qchGRCuC2RugA4eQ9fUrR4Yuycac3caiaaay" } }
The signature property is used to associate a signature with a graph of information. The signature property is typically not included in the canonicalized graph that is then digested, and digitally signed.
The following example demonstrates how a signature on the graph identified by
the subject http://example.com/people#jane
is expressed using
a JSON-LD signature:
{ "@context": [ "https://w3id.org/security/v1", { "foaf": "http://xmlns.com/foaf/0.1/" } ] "@graph": { "@id": "http://example.com/people#jane", "@type": "foaf:Person", "foaf:name": "Jane Doe", "foaf:homepage": "http://example.org/jane" }, "signature": { "@type": "GraphSignature2012", "creator": "http://example.com/people/john-doe#key-5", "signatureValue": "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI=" } }
The signature value is used to express the output of the signature algorithm expressed in base-64 format.
The following example shows how the output of the signature algorithm can be encoded in JSON-LD:
{ "@context": [ "https://w3id.org/security/v1", { "foaf": "http://xmlns.com/foaf/0.1/" } ] "@graph": { "@id": "http://example.com/people#jane", "@type": "foaf:Person", "foaf:name": "Jane Doe", "foaf:homepage": "http://example.org/jane" }, "signature": { "@type": "GraphSignature2012", "creator": "http://example.com/people/john-doe#key-5", "signatureValue": "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI=" } }
The signature algorithm is used to specify the cryptographic signature function to use when digitally signing the digest data. Typically, text to be signed goes through three steps: 1) canonicalization, 2) digest, and 3) signature. This property is used to specify the algorithm that should be used for step #3. A signature class typically specifies a default signature algorithm, so this property rarely needs to be used in practice when specifying digital signatures.
The following example shows how the signature algorithm can be specified for a particular class of signatures:
{ "@context": "https://w3id.org/security/v1", "@id": "https://w3id.org/security#GraphSignature2012", "@type": "Signature", "canonicalizationAlgorithm": "https://w3id.org/jsonld#UGNA2012", "digestAlgorithm": "http://example.com/digests#sha512", "signatureAlgorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1", }
Examples of specific services include discovery services, social networks, file storage services, and verifiable claim repository services.
The following example shows how service is defined:
{ ... "service": [{ "id":"did:example:123456789abcdefghi#vcs", "type": "VerifiableCredentialService", "serviceEndpoint": "https://example.com/vc/" }] }
A network address at which a service operates on behalf of a controller. Examples of specific services include discovery services, social networks, file storage services, and verifiable claim repository services. Service endpoints might also be provided by a generalized data interchange protocol, such as extensible data interchange.
The following example shows how service is defined:
{ ... "service": [{ "id":"did:example:123456789abcdefghi#vcs", "type": "VerifiableCredentialService", "serviceEndpoint": "https://example.com/vc/" }] }
The x509CertificateChain property is used to associate a chain of X.509 Certificates with a proof. The value of this property is an ordered list where each value in the list is an X.509 Certificate expressed as a DER PKIX format, that is encoded with multibase using the base64pad variant. The certificate directly associated to the verification method used to verify the proof MUST be the first element in the list. Subsequent certificates in the list MAY be included where each one MUST certify the previous one.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with a link to an associated x509CertificateChain
:
{ ... "proof": { "type": "Ed25519Signature2018", "created": "2020-04-03T18:03:33Z", "x509CertificateChain": [ "MIIC/jCCAeYCCQDqa4lnWhygnDANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJT RTEQMA4GA1UECgwHSXNzdWVyIDEPMA0GA1UECwwGaXNzdWVyMQ8wDQYDVQQDDAZp c3N1ZXIwHhcNMjEwNDE2MDMwMTUyWhcNMjQwMTExMDMwMTUyWjBBMQswCQYDVQQG EwJTRTEQMA4GA1UECgwHSXNzdWVyIDEPMA0GA1UECwwGaXNzdWVyMQ8wDQYDVQQD DAZpc3N1ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYa1IJIrKr R5SHPfyOCWKuwcJHnDjTt+8cC7SLwtrfg3vazE+uRSP8cS7RitvMqK1YyC/pthJI zJlzF3OqcRQENjPfzQaD6J/55TWhwYfNj5IOVDCcZflfe+fgdl+N2mhrkIADqK3i Z5fOp5M2DN0m3XVhUllOHQ1dX6IRGCFrDV0ho2uOY+mmy3qIB3DRBLqd9pCN7ddr z+3uTRUYyuRiLdvvc7Myjq7CrNkiqr5yedMXwM9Bi3GVUIZ3L4MKgyCf7XZ0TMoX i4FVWbi4O1caKM0foglpRzGQM0IPgwQ/JR5u+rWaNx5XdowraWqU0LziznibvuFI HTpcQVmO0zNDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAJPFM32NBdAsGnuChQ9 1A66HvVwQeC/r2wJFVj3jg7h7lTYjmaHKoRP3J5UGmHo8fTbIxyJPKoXZ3qoj31Y uBFKxNaNjSrPTOUv/4injvqjkdCvQdy0iuQaNtQJSkse4t/fnQ+DMC+E3cNii8Yj 0Z+T3oJL1PCg01N6uL8KtooEmnUGzIzuZ2naokgwaiEOU2CCnJOCKYxz22cxqfNm sGy1keqt6/bE64UnJRgETdqHzZTO0013ZtvDiwjGo3CZg4FBi/O722XnxbzuFIPZ WWOOb9VaH+AE4lNei6i/CDY/WcgpP0GDIj3z6lCeLtiSagiQQPYxIz2sBxC1OKVU 7CE=" ], "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ktzmVCTovhKWKxnMwDtMnmpUAUF1n7sqbdNmOV0TkxCTb2eHATO6iP7wqjyl_CMehHKnqgW6t9SW4q9TdbCxAg", "proofPurpose": "assertionMethod", "verificationMethod": "did:key:z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y#z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y" } }
The x509CertificateFingerprint property is used to associate an X.509 Certificate with a proof via its fingerprint. The value is a multihash encoded then multibase encoded value using the base64pad variant. It is RECOMMENDED that the fingerprint value be the SHA-256 hash of the X.509 Certificate.
The following example demonstrates how a proof is expressed using
a JSON-LD proof with a link to an associated x509CertificateFingerprint
:
{ ... "proof": { "type": "Ed25519Signature2018", "created": "2020-04-03T18:03:33Z", "x509CertificateFingerprint": "MEiB6BbyLEylDZbtIbjpj5nM+QJQyPGartYi4x6Cj0Jl2FQ==", "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ktzmVCTovhKWKxnMwDtMnmpUAUF1n7sqbdNmOV0TkxCTb2eHATO6iP7wqjyl_CMehHKnqgW6t9SW4q9TdbCxAg", "proofPurpose": "assertionMethod", "verificationMethod": "did:key:z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y#z6MkkUNcUWxAbxamK2Spp92mKWoXddS3tTqBKe8VTGExzX2Y" } }