A did:key method resolver.
npm install @digitalcredentials/did-method-key
> A DID (Decentralized Identifier) method driver for the did-io library and for standalone use
- Background
* Example DID Document
- Security
- Install
- Usage
- Contribute
- Commercial Support
- License
(Forked from digitalbazaar/did-method-key v1.0.0
to provide TypeScript compatibility.)
See also (related specs):
* Decentralized Identifiers (DIDs)
* Linked Data Cryptographic Suite Registry
* Linked Data Proofs
A did:key method driver for the did-io
client library and for standalone use.
The did:key method is used to express public keys in a way that doesn't
require a DID Registry of any kind. Its general format is:
```
did:key:
So, for example, the following DID would be derived from a base-58 encoded
ed25519 public key:
``
did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH
That DID would correspond to the following DID Document:
`json`
{
"@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 keyAgreement key is a Curve25519 public key (suitable fored2curve-js
Diffie-Hellman key exchange) that is deterministically _derived_ from the source
Ed25519 key, using .
Note that this derived key is optional -- there's currently
no proof
that this is safe to do.
Requires Node.js 12+
To install from npm:
``
npm install --save @digitalcredentials/did-method-key
To install locally (for development):
``
git clone https://github.com/digitalcredentials/did-method-key-js.git
cd did-method-key-js
npm install
To generate a new key and get its corresponding did:key method DID Document:
`js
const didKeyDriver = require('@digitalcredentials/did-method-key').driver();
// generate did:key using Ed25519 key type by default
const {didDocument, keyPairs, methodFor} = await didKeyDriver.generate();
// print the DID Document above
console.log(JSON.stringify(didDocument, null, 2));
// keyPairs will be set like so ->
Map(2) {
'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv#z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv' => Ed25519VerificationKey2020 {
id: 'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv#z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv',
controller: 'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv',
type: 'Ed25519VerificationKey2020',
publicKeyMultibase: 'z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv',
privateKeyMultibase: 'z3zDo1wXuXGcFkJa9SPE7VYpdutmHq8gJsvFRMKJckTWMykoHsAjWNbHXqzrZ8qa7aWdDTjmJNJ1amYEG2mCvZZeY'
},
'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv#z6LSeRSE5Em5oJpwdk3NBaLVERBS332ULC7EQq5EtMsmXhsM' => X25519KeyAgreementKey2020 {
id: 'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv#z6LSeRSE5Em5oJpwdk3NBaLVERBS332ULC7EQq5EtMsmXhsM',
controller: 'did:key:z6MkuBLrjSGt1PPADAvuv6rmvj4FfSAfffJotC6K8ZEorYmv',
type: 'X25519KeyAgreementKey2020',
publicKeyMultibase: 'z6LSeRSE5Em5oJpwdk3NBaLVERBS332ULC7EQq5EtMsmXhsM',
privateKeyMultibase: 'z3weeMD56C1T347EmB6kYNS7trpQwjvtQCpCYRpqGz6mcemT'
}
}
`
methodFor is a convenience function that returns a public/private key pairsigner()
instance for a given purpose. For example, a verification key (containing a and verifier() functions) are frequently useful forjsonld-signatures orvc-js operations. After generating
a new did:key DID, you can do:
`js@digitalbazaar/minimal-cipher
// For signing Verifiable Credentials
const assertionKeyPair = methodFor({purpose: 'assertionMethod'});
// For Authorization Capabilities (zCaps)
const invocationKeyPair = methodFor({purpose: 'capabilityInvocation'});
// For Encryption using `
const keyAgreementPair = methodFor({purpose: 'keyAgreement'});
Note that methodFor returns a key pair that contains both a public and privatekeyPairs
key pair (since it has access to the map from generate()).publicMethodFor
This makes it useful for _signing_ and _encrypting_ operations (unlike the that's returned by get(), below).
If you already have an Ed25519VerificationKey2020 public key object (as an
LDKeyPair instance, or a plain key description object), you can turn it into
a DID Document:
`js`
const {didDocument} = await didKeyDriver.publicKeyToDidDoc({publicKeyDescription});
#### Getting a full DID Document from a did:key DID
To get a DID Document for an existing did:key DID:
`js`
const did = 'did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T';
const didDocument = await didKeyDriver.get({did});
(Results in the example DID Doc above).
#### Getting just the key object by key id
You can also use a .get() to retrieve an individual key, if you know it's iddocumentLoader
already (this is useful for constructing s for JSON-LD Signature@context
libs, and the resulting key does include the appropriate ).
`js
const verificationKeyId = 'did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T#z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T';
await didKeyDriver.get({url: verificationKeyId});
// ->
{
"@context": "https://w3id.org/security/suites/ed25519-2020/v1",
"id": "did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T#z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T",
"type": "Ed25519VerificationKey2020",
"controller": "did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T",
"publicKeyMultibase": "z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T"
}
const keyAgreementKeyId = 'did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T#z6LSotGbgPCJD2Y6TSvvgxERLTfVZxCh9KSrez3WNrNp7vKW';
await didKeyDriver.get({url: keyAgreementKeyId});
// ->
{
"@context": "https://w3id.org/security/suites/x25519-2020/v1",
"id": "did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T#z6LSotGbgPCJD2Y6TSvvgxERLTfVZxCh9KSrez3WNrNp7vKW",
"type": "X25519KeyAgreementKey2020",
"controller": "did:key:z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T",
"publicKeyMultibase": "z6LSotGbgPCJD2Y6TSvvgxERLTfVZxCh9KSrez3WNrNp7vKW"
}
`
Often, you have just a did:key DID, and you need to get a key for aassertionMethod
particular _purpose_ from it, such as an key to verify akeyAgreement
VC signature, or a key to encrypt a document for that DID's
controller.
For that purpose, you can use a combination of get() and publicMethodFor:
`jspublicMethodFor()
// Start with the DID
const didDocument = await didKeyDriver.get({did});
// This lets you use to get a key for a specific purpose
const keyAgreementData = didKeyDriver.publicMethodFor({
didDocument, purpose: 'keyAgreement'
});
const assertionMethodData = didKeyDriver.publicMethodFor({
didDocument, purpose: 'assertionMethod'
});
// If you're using a crypto-ld driver harness, you can create key instancesverify()
// which allow you to get access to a function.`
const assertionMethodPublicKey = await cryptoLd.from(assertionMethodData);
const {verify} = assertionMethodPublicKey.verifier();
publicMethodFor will return undefined` if no key is found for a given
purpose.
See the contribute file!
PRs accepted.
If editing the Readme, please conform to the
standard-readme specification.
* MIT License - DCC - TypeScript compatibility.
* New BSD License (3-clause) © 2020-2021 Digital Bazaar - Initial implementation.