Decentralized Identifiers (DIDs) are a new type of identifier for verifiable, decentralized digital identity. These new identifiers are designed to enable the controller of a DID to prove control over it and to be implemented independently of any centralized registry, identity provider, or certificate authority. These sorts of identifiers often utilize a heavy-weight registry, such as ones utilizing Decentralized Ledger Technologies (DLT), to create, read, update, and deactivate DIDs. This specification describes a non-registry based DID Method based on expanding a cryptographic public key into a DID Document. This approach provides the simplest possible implementation of a DID Method that is able to achieve many, but not all, of the benefits of utilizing DIDs.
Portions of the work on this specification have been funded by the United States Department of Homeland Security's Science and Technology Directorate under contract HSHQDC-17-C-00019. 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.
Decentralized Identifiers (DIDs) [[DID-CORE]] are a new type of identifier for verifiable, decentralized digital identity. These new identifiers are designed to enable the controller of a DID to prove control over it and to be implemented independently of any centralized registry, identity provider, or certificate authority. These sorts of identifiers often utilize a heavy-weight registry, such as ones utilizing Decentralized Ledger Technologies (DLT), to create, read, update, and deactivate DIDs.
While DLT-based DID Methods have great decentralization characteristics, and some of the more centralized DID Methods provide strong system control guarantees, the general approaches tend to be expensive to setup and operate. Some use cases requiring DIDs do not need the guarantees provided by these heavy-weight systems. For example, a DID that will only be used for a single, ephemeral interaction might not need to be registered, updated, or deactivated, or where private keys are protected by software or hardware isolation. These are a few of the cases where using did:key might offer unique benefits.
Use of did:key for long-lived use cases is only recommended when accompanied with high confidence in hardware isolation.
The rest of this document outlines the syntax for the did:key method, the operations it supports, and some security and privacy considerations that implementers might want to be aware of when implementing.
The format for the did:key method conforms to the [[DID-CORE]]
specification and is simple. It consists of the did:key
prefix,
followed by a Multibase [[MULTIBASE]] base58-btc encoded value that is a
concatenation of the Multicodec [[MULTICODEC]] identifier for the public key
type and the raw bytes associated with the public key format.
The ABNF for the key format is described below:
did-key-format := did:key:<mb-value> mb-value := z[a-km-zA-HJ-NP-Z1-9]+
Alternatively, the encoding rules can also be thought of as the application of a series of transformation functions on the raw public key bytes:
did-key-format := did:key:MULTIBASE(base58-btc, MULTICODEC(public-key-type, raw-public-key-bytes))A simple example of a valid Ed25519 did:key DID is:
did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
The following section outlines the DID operations for the did:key method. Implementers might note that this DID Method is purely generative, requiring no look ups in a registry. Since did:key values are not stored in any registry, they cannot be updated or deactivated.
Creating a did:key value consists of creating a cryptographic key pair
and encoding the public key using the format provided in Section . The creation of a DID Document is also performed by taking
the public key value and expanding it into DID Document. An example is given
below that expands the ed25519 did:key
did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
into its
associated DID Document:
{ "@context": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1", "https://w3id.org/security/suites/x25519-2020/v1" ], "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "verificationMethod": [{ "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "type": "Ed25519VerificationKey2020", "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" }], "authentication": [ "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" ], "assertionMethod": [ "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" ], "capabilityDelegation": [ "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" ], "capabilityInvocation": [ "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" ], "keyAgreement": [{ "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p", "type": "X25519KeyAgreementKey2020", "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "publicKeyMultibase": "z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p" }] }
The following algorithm can be used for expanding a did:key identifier to a DID Document. An identifier and options are the required inputs. Implementations are expected to set a reasonable default for the options.publicKeyFormat value such as `JsonWebKey2020` or `Multikey`. The options.enableExperimentalPublicKeyTypes value SHOULD be set to `false`. The options.defaultContext value SHOULD be set to an array where the first element is the string value `https://www.w3.org/ns/did/v1`. Defaults MAY be overridden by the caller of this algorithm. A document is the resulting output.
Any alternative algorithm can be used that produces an equivalent result to the output from the algorithm above.
The following algorithm can be used for decoding a multibase-encoded multicodec value into a verification method that is suitable for verifying digital signatures. An identifier, multibaseValue, and options are the required inputs. A verificationMethod is the resulting output.
Multicodec hexadecimal value | public key byte length | Description |
---|---|---|
`0xe7` | 33 bytes | secp256k1-pub - Secp256k1 public key (compressed) |
`0xec` | 32 bytes | x25519-pub - Curve25519 public key |
`0xed` | 32 bytes | ed25519-pub - Ed25519 public key |
`0x1200` | 33 bytes | p256-pub - P-256 public key (compressed) |
`0x1201` | 49 bytes | p384-pub - P-384 public key (compressed) |
`0x1202` | ?? bytes | p521-pub - P-521 public key (compressed) |
`0x1205` | ?? bytes | rsa-pub - RSA public key. DER-encoded ASN.1 type RSAPublicKey according to IETF RFC 8017 (PKCS #1) |
The following algorithm can be used for expanding a multibase-encoded multicodec value to decoded public key components. A multibaseValue and options are the required inputs. A decodedPublicKey is the output.
There are 2 categories of JWK expressions for multicodec encoded public keys.
Standard JWK representations can be found under the IANA registry for JSON Object Signing and Encryption (JOSE) .
In cases where a key type has not been formally standardized yet a specification describing the key encoding is provided.
BLS12381 is the only instance of such a key type in the current method specification. See this document tracking its proposed standardization at IETF. See draft-looker-cose-bls-key-representations.
Implementations MUST conform to the normative requirements of the RFCs and specifications above.
The following algorithm can be used to encode a multicodec value to a JSON Web Key. A multicodecValue, rawPublicKeyBytes are the required inputs. An encodedJWK is the output.
kty
, crv
, n
,e
values for the JWK representation of the key type identified by multicodecValue.
y
is required member of the public key,
perform elliptic curve expansion by applying
decompression algorithm specified here.
to obtain y
and x
.
Otherwise simply encode x
according to the associated RFCs.
d
is NOT present.
Address RSA encoding for DER encoded RSA keys.
Address BLS12381 Encoding.
The following algorithm can be used for decoding a multibase-encoded multicodec value into a verification method that is suitable for verifying that encrypted information will be received by the intended recipient. An identifier, multibaseValue, and options are the required inputs. A verificationMethod is the resulting output.
Multicodec hexadecimal value | public key byte length | Description |
---|---|---|
`0xec` | 32 bytes | x25519-pub - Curve25519 public key |
The following algorithm can be used to transform a multibase-encoded multicodec value to public encryption key components that are suitable for encrypting messages to a receiver. A mathematical proof elaborating on the safety of performing this operation is available in [[THORMARKER]]. A multibaseValue and options are the required inputs. A publicEncryptionKey is the output.
The following algorithm is used to generate the array for the `@context` property in the DID Document. A document and options are the required inputs. A contextArray is the output.
`type` value | Context URL |
---|---|
`Ed25519VerificationKey2020` | https://w3id.org/security/suites/ed25519-2020/v1 |
`X25519KeyAgreementKey2020` | https://w3id.org/security/suites/x25519-2020/v1 |
`JsonWebKey2020` | https://w3id.org/security/suites/jws-2020/v1 |
`Multikey` | There is currently no JSON-LD Context that defines the Multikey type. This is expected to be defined by the VC2WG in 2022 or 2023. |
Reading a did:key value is a matter of deterministically expanding the value to a DID Document. This process is described in Section .
This DID Method does not support updating the DID Document.
This DID Method does not support deactivating the DID Document.
For a full list of test vectors see test vectors.
We provide only the verificationMethod
section of the DID Document in these examples.
These DID always start with z6Mk
.
... "verificationMethod": [ { "id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "type": "JsonWebKey2020", "controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "publicKeyJwk": { "kty": "OKP", "crv": "Ed25519", "x": "O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik" } }, { "id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW", "type": "JsonWebKey2020", "controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "publicKeyJwk": { "kty": "OKP", "crv": "X25519", "x": "W_Vcc7guviK-gPNDBmevVw-uJVamQV5rMNQGUwCqlH0" } } ], ...
... "verificationMethod": [ { "id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "type": "Ed25519VerificationKey2020", "controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "publicKeyMultibase": "z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp" }, { "id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW", "type": "X25519KeyAgreementKey2020", "controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp", "publicKeyMultibase": "z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW" } ], ...
did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf
These DID always start with z6LS
.
did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ
These DID always start with zQ3s
.
did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2 did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N
These DID always start with zUC7
.
did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW
These DID always start with zDn
.
did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169 did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv
These DID always start with z82
.
did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9 did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54
These DID always start with z2J9
.
did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7 did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f
See also RSA Public Key Representation.
These DID always start with z4MX
.
did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i
These DID always start with zgg
.
did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2
There are a number of security and privacy considerations that implementers will want to take into consideration when implementing this specification.
The did:key method is a purely generative method, which means that updates are not supported. This can be an issue if a did:key is expected to be used over a long period of time. For example, if a did:key is ever compromised, it is not possible to rotate the compromised key. For this reason, using a did:key for interactions that last weeks to months is strongly discouraged.
The did:key method is a purely generative method, which means that deactivations are not supported. This can be an issue if a did:key is expected to be used over a long period of time. For example, if a did:key is ever compromised, it is not possible to deactivate the DID to stop an attacker from using it. For this reason, using a did:key for interactions that last weeks to months is strongly discouraged.
Some implementations might utlize a key derivation function when converting from
an ed25519 public key to a Curve25519 ECDH key, used in the
keyAgreement
verification method. It is expected that this is a
relatively safe operation, but implementers might consider that there exists no
mathematical proof that confirms this assumption.
Since there is no support for update and deactivate for the did:key method, it is not possible to recover from a security compromise. For this reason, using a did:key for interactions that last weeks to months is strongly discouraged.
An RSA public key for did:key is represented as a DER-encoded
RSAPublicKey
data structure as specified in
RFC
3447 (PKCS #1), as registered in the Multicodec table (code
0x1205
).
DER is a canonical encoding of ASN.1 values. For the aid of implementers who do not fully support ASN.1/DER, the following subsections describe the public key representation for RSA public keys that use some common parameters.
[48, 130, 1, 10, 2, 130, 1, 1, 0]
[0]
if and only if the
most-significant bit of modulus is set.[2, 3, 1, 0, 1]
See also the example 2048-bit test vector.
[48, 130, 2, 10, 2, 130, 2, 1, 0]
[0]
if and only if the
most-significant bit of modulus is set.[2, 3, 1, 0, 1]
See also the example 4096-bit test vector.
The Working Group would like to thank the following individuals for reviewing and providing feedback on the specification (in alphabetical order):
TBD...