DID Registration
Updated: June 2, 2020
Registering a Decentralized Identifier (DID) is the process of creating a unique identifier on a distributed ledger and associating it with one or more public keys. You can prove you are the owner/controller of a DID to anyone you choose, as long as you possess the corresponding private key(s). DIDs form the foundation of decentralized identity. The W3C Credentials Community Group's DID spec explains the DID technical standard in more detail.
The way you claim a DID and publish your public keys depends on which distributed ledger you use to register your DID. Each ledger has its own rules, formats, and quirks. Thankfully, the DID standard defines common ways to deal with DIDs, and our services expose the standard to you in a simple web API. Currently, we're developing support for the following ledgers:
- Bitcoin
- Ethereum, via uPort
- Sovrin
Our intention is to be chain agnostic, enabling users to choose a DID variant that runs on their preferred ledger. Each ledger that is compliant with DID standards has an associated DID "method" - a set of rules that govern how DIDs are anchored onto the ledger.
Currently our registration services support the following two DID methods:
ion-test | test |
---|---|
A DID method known as the Identity Overlay Network (ION). ION is a method that registers DIDs on Bitcoin. It uses a protocol known as SideTree to batch DID operations into individual Bitcoin transactions, such that the throughput of ION is much higher than typical Bitcoin transactions. Currently, the ion-test method registers DIDs on Bitcoin's testnet. It does not require any cryptocurrency or monetary value, and should only be used for test and development DIDs. To learn more about ION or to contribute to its active development, visit the ION GitHub repository. |
A mock method for generating test DIDs. It is not connected to any blockchain or ledger; all DIDs are stored in a Microsoft data store. DIDs on the test method are deleted each week. To try out DID registration with our test method, you can use our example user agent chrome extension, or follow the instruction in this article. |
Registration via our chrome extension
We've built a test user agent that implements our registration APIs using the test
DID method; it is appropriate if you want to try out registration without writing any code. Over time we plan to provide production-ready user agent applications across platforms including mobile and desktop. To register a DID via our user agent:
- Install the chrome extension by following this guide.
- Once installed, open the extension by clicking on the icon in Google Chrome.
- Type in a friendly name for your DID and click create.
Congratulations, you have created your first DID! You can now move on to using this DID to perform authentication.
Registration via our APIs using ion-test
If you're a developer who wants to allow users to register DIDs from your app or service, you can implement DID registration using the ion-test
method by following the steps below.
Prerequisites
In order to complete this registration tutorial, you'll need:
- NPM and NodeJS 8 or later installed on your machine.
Generate a key pair
Next, you need to generate an asymmetric key pair using the key types supported by your target ledger. The ion-test
method supports Secp256k1 keys. You can generate your keys as a JSON Web Key (JWK) file using the did-auth-jose
library. First install the package:
npm install @decentralized-identity/did-auth-jose@0.1.12
In the same directory, copy & paste the following into a new javascript file called generate-keys.js
:
var didAuth = require('@decentralized-identity/did-auth-jose');
var fs = require('fs');
(async () => {
const kid = '#key-1';
const privKey = await didAuth.EcPrivateKey.generatePrivateKey(kid);
const pubKey = privKey.getPublicKey();
pubKey.defaultSignAlgorithm = 'ES256K';
fs.writeFileSync('./private.jwk', JSON.stringify(privKey));
fs.writeFileSync('./public.jwk', JSON.stringify(pubKey));
})();
Run the script to generate a new Secp256k1 key pair.
node generate-keys.js
Generate a JWS
To register a DID using these keys, you must sign a registration request with your private key. A DID registration request must be formatted as a JSON Web Signature in JSON serialization format with the following payload:
{
"@context": "https://w3id.org/did/v1",
"publicKey": [
{
"id": "#key-1",
"type": "Secp256k1VerificationKey2018",
"publicKeyJwk": {
"kty": "EC",
"kid": "#key-1",
"crv": "P-256K",
"x": "p7Mt2Z6hXu8g_I62owqmNcrj3t1nRoWslB8eQ7JP0yY",
"y": "KRp11VQmCLjvxTk7TWx9Pbj2fHPt5SoXQwzEYs1Cnac",
"use": "verify",
"defaultEncryptionAlgorithm": "none",
"defaultSignAlgorithm": "ES256K"
}
}
],
"service": [
{
"id": "IdentityHub",
"type": "IdentityHub",
"serviceEndpoint": {
"@context": "schema.identity.foundation/hub",
"@type": "UserServiceEndpoint",
"instance": [
"did:test:hub.id"
]
}
}
]
}
property | value | description |
---|---|---|
@context |
https://w3id.org/did/v1 |
Must be https://w3id.org/did/v1 . |
publicKey |
[] |
An array of public keys in a format accepted by the W3C DID specfiication. Here, we use the (JWK) format. |
service |
[] |
An array of services that can be used to communicate with the DID. Here, we list one identity hub as an available service. |
You can also use the did-auth-jose
library to create a JWS. In the same directory, copy & paste the following into a new javascript file called make-jws.js
:
var fs = require('fs');
var path = require('path');
var didAuth = require('@decentralized-identity/did-auth-jose');
// load JWKs from files
const jwkPriv = JSON.parse(fs.readFileSync(path.resolve(__dirname, './private.jwk'), 'ascii'));
const jwkPub = JSON.parse(fs.readFileSync(path.resolve(__dirname, './public.jwk'), 'ascii'));
// load JWK into an EcPrivateKey object
const privateKey = didAuth.EcPrivateKey.wrapJwk(jwkPriv.kid, jwkPriv);
async function makeJws() {
// construct the JWS payload
const body = {
"@context": "https://w3id.org/did/v1",
publicKey: [
{
id: jwkPub.kid,
type: "Secp256k1VerificationKey2018",
publicKeyJwk: jwkPub
}
],
service: [
{
id: "IdentityHub",
type: "IdentityHub",
serviceEndpoint: {
"@context": "schema.identity.foundation/hub",
"@type": "UserServiceEndpoint",
instance: [
"did:test:hub.id",
]
}
}
],
};
// Construct the JWS header
const header = {
alg: jwkPub.defaultSignAlgorithm,
kid: jwkPub.kid,
operation:'create',
proofOfWork:'{}'
};
// Sign the JWS
const cryptoFactory = new didAuth.CryptoFactory([new didAuth.Secp256k1CryptoSuite()]);
const jwsToken = new didAuth.JwsToken(body, cryptoFactory);
const signedBody = await jwsToken.signAsFlattenedJson(privateKey, {header});
// Print out the resulting JWS to the console in JSON format
console.log(JSON.stringify(signedBody));
}
makeJws();
Run the above script, which will output a signed JWS in JSON format:
node make-jws.js
Call the registration API
Now that you've generated your new key pair securely on your own machine, you can publish your public key onto the distributed ledger with the following API call to https://beta.ion.microsoft.com/api/1.0/register
:
POST /api/1.0/register HTTP/1.1
Host: beta.ion.microsoft.com
Content-Type: application/json
Content-Length: 1061
{
"header": {
"alg": "ES256K",
"kid": "#key-1",
"operation": "create",
"proofOfWork": "{}"
},
"payload": "eyJAY29udGV4dCI6Imh0dHBzOi8vdzNpZC5vcmcvZGlkL3YxIiwicHVibGljS2V5Ijp...",
"signature": "MEYCIQCbZ7x59qU7ZgECKXWdLnWUSRTHbOUQGP81LP6OLaOu5gIhAM9iSYv08S-Qa..."
}
The following curl command will produce this request for you:
curl -v -H "Content-Type: application/json" --data "{'header':{'alg':'ES256K', ... " -X POST https://beta.ion.microsoft.com/api/1.0/register
If your request succeeded, you should receive the following response:
HTTP/1.1 200 OK
Content-Length: 395
Content-Type: application/json
{
"@context": "https://w3id.org/did/v1",
"publicKey": [
{
"id": "#key-1",
"type": "Secp256k1VerificationKey2018",
"publicKeyJwk": {
"kty": "EC",
"kid": "#key-1",
"crv": "P-256K",
"x": "p7Mt2Z6hXu8g_I62owqmNcrj3t1nRoWslB8eQ7JP0yY",
"y": "KRp11VQmCLjvxTk7TWx9Pbj2fHPt5SoXQwzEYs1Cnac",
"use": "verify",
"defaultEncryptionAlgorithm": "none",
"defaultSignAlgorithm": "ES256K"
}
}
],
"service": [
{
"id": "IdentityHub",
"type": "IdentityHub",
"serviceEndpoint": {
"@context": "schema.identity.foundation/hub",
"@type": "UserServiceEndpoint",
"instance": [
"did:test:hub.id"
]
}
}
],
"id": "did:ion-test:EiCrsG_DLDmSKic1eaeJGDtUoC1dj8tj19nTRD9ODzAjaQ"
}
property | value | description |
---|---|---|
@context |
https://w3id.org/did/v1 |
Must be https://w3id.org/did/v1 . |
publicKey |
[] |
An array of public keys in a format accepted by the W3C DID specfiication. Here, we use the (JWK) format. |
service |
[] |
An array of services that can be used to communicate with the DID. Here, we list one identity hub as an available service. |
id |
did:ion-test:EiCrsG_DLDmSKic1eaeJGDtUoC1dj8tj19nTRD9ODzAjaQ |
The DID you have just registered via the ion-test method. |
Wait for registration to complete
The ion-test
method queues DID registration requests and writes them to Bitcoin's testnet as quickly as possible. Registration can complete as quickly as 2 minutes, but often takes as long as 30 minutes. During this time, the ION method is working actively to add transactions to the Bitcoin testnet ledger that will refer to your newly created DID document.
Call the discovery API
To see if your DID registration is complete, you can use the discovery API. If your DID can be resolved via this API, then your DID has been successfully registered!
See something missing? We'd love your feedback and input on the Verifiable Credentials preview. Please contact us. When you use Microsoft DID Services, you agree to the DID Preview Agreement and the Microsoft Privacy Statement.