DIDs#
We talk a lot about DIDs in a past videos. DID is a core of SSI and create cryptographic verifieble, decentralised, resolvable identifier. Decentralized Identifier (DID) is a unique, persistent, and cryptographically verifiable identifier that allows individuals, organizations, or devices to establish and manage their digital identities independently. DIDs are used in decentralized identity systems, enabling users to have control over their data and interact securely without relying on a centralized authority.
## DID Document and DID Identifier A DID (Decentralized Identifier) document is a structured, machine-readable JSON or JSON-LD document that contains essential information associated with a specific DID. It serves as a "public profile" for a decentralized identity, providing the necessary details for verifying signatures, encrypting/decrypting messages, and interacting with the identity's associated services.The DID document typically includes:
The DID itself: A unique identifier that represents the decentralized identity.
Public keys: One or more public keys associated with the DID, used for cryptographic operations such as verifying signatures and encrypting messages.
Authentication methods: Mechanisms to prove control of the DID, which typically involve the use of public keys.
Service endpoints: URLs or other identifiers of services related to the DID, such as profile information, communication channels, or data repositories.
Other metadata: Additional information related to the DID, such as timestamps, controller information, or specific DID method details.
The DID document’s information allows other parties to trust and interact securely with the associated DID without relying on a centralized authority. DID documents are created, updated, and deactivated according to the rules and processes defined by the DID method associated with the DID. They are usually stored on distributed ledgers, blockchains, or other decentralized networks, making them globally resolvable and cryptographically verifiable.
{
"@context": "https://w3id.org/security/v2",
"publicKey": [
{
"id": "did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q#primary",
"usage": "signing",
"type": "Secp256k1VerificationKey2018",
"publicKeyHex": "022ca63fffbd8b6dd7e54fa88b76d5245700ac81657fd59a03b73e4325ba1e19ba"
},
{
"id": "did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q#recovery",
"usage": "recovery",
"type": "Secp256k1VerificationKey2018",
"publicKeyHex": "0390d67bfbfc80d00edc7080a4c91f1c844208fabd03e158a5910f5d1601e69eb5"
}
],
"authentication": [
"did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q#primary"
],
"assertionMethod": [
"did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q#primary"
],
"id": "did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q"
}
DID identifier
did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBeU1tTmhOak5tWm1aaVpEaGlObVJrTjJVMU5HWmhPRGhpTnpaa05USTBOVGN3TUdGak9ERTJOVGRtWkRVNVlUQXpZamN6WlRRek1qVmlZVEZsTVRsaVlTSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TXprd1pEWTNZbVppWm1NNE1HUXdNR1ZrWXpjd09EQmhOR001TVdZeFl6ZzBOREl3T0daaFltUXdNMlV4TlRoaE5Ua3hNR1kxWkRFMk1ERmxOamxsWWpVaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiTkJqblFlQVRuTXVJQUFrZTlEcFhDeXAzcmJzcnBsQWFRQ1A0ZEl2b3NfNVJZRnJTc2VDdnBSY3k1XzFOMUpObzB2WEpDdWVVVmZvaHJtNHROenM2cmcifQ
Parsed DIDs
{
reference: 'did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBeU1tTmhOak5tWm1aaVpEaGlObVJrTjJVMU5HWmhPRGhpTnpaa05USTBOVGN3TUdGak9ERTJOVGRtWkRVNVlUQXpZamN6WlRRek1qVmlZVEZsTVRsaVlTSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TXprd1pEWTNZbVppWm1NNE1HUXdNR1ZrWXpjd09EQmhOR001TVdZeFl6ZzBOREl3T0daaFltUXdNMlV4TlRoaE5Ua3hNR1kxWkRFMk1ERmxOamxsWWpVaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiTkJqblFlQVRuTXVJQUFrZTlEcFhDeXAzcmJzcnBsQWFRQ1A0ZEl2b3NfNVJZRnJTc2VDdnBSY3k1XzFOMUpObzB2WEpDdWVVVmZvaHJtNHROenM2cmcifQ',
did: 'did:elem:EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q',
method: 'elem',
identifier: 'EiBa0KyUWgvMdkt_ywullSPac2kyOkRP5JRtHSeICQ1t6Q',
path: '',
fragment: '',
query: '',
param: ';elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBeU1tTmhOak5tWm1aaVpEaGlObVJrTjJVMU5HWmhPRGhpTnpaa05USTBOVGN3TUdGak9ERTJOVGRtWkRVNVlUQXpZamN6WlRRek1qVmlZVEZsTVRsaVlTSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TXprd1pEWTNZbVppWm1NNE1HUXdNR1ZrWXpjd09EQmhOR001TVdZeFl6ZzBOREl3T0daaFltUXdNMlV4TlRoaE5Ua3hNR1kxWkRFMk1ERmxOamxsWWpVaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiTkJqblFlQVRuTXVJQUFrZTlEcFhDeXAzcmJzcnBsQWFRQ1A0ZEl2b3NfNVJZRnJTc2VDdnBSY3k1XzFOMUpObzB2WEpDdWVVVmZvaHJtNHROenM2cmcifQ'
}
DID Actions#
It is four posible DID Actions.
Creating a DID: Generating a new identifier and associating it with a DID document, which contains public key material and service endpoints for the identity. For DIDs on blockchaine we could see term Anhoring. DID anchoring refers to the process of registering a Decentralized Identifier (DID) and its associated DID document on a distributed ledger or blockchain. Anchoring provides a secure, tamper-proof, and verifiable record of the DID’s existence and its associated information, making it an essential component of decentralized identity systems.
Resolving a DID: Retrieving the DID document associated with a specific DID, which is essential for verifying signatures, encrypting/decrypting messages, and interacting with the identity’s associated services.
Updating a DID: Modifying the DID document, such as adding or updating public keys, service endpoints, or other metadata. This action typically requires authorization from the DID controller.
Deactivating a DID: Marking a DID as inactive, rendering it unusable for future interactions. This action also usually requires authorization from the DID controller. DID resolution is a main and mandatory operations. Every did method has create procedure.
DID method#
Method is concrete implementation that defines the rules and processes for did actions on a particular distributed ledger, blockchain, or other decentralized network. DID methods provide a standardized way to manage DIDs and their associated DID documents, enabling interoperability between different decentralized identity systems. Each DID method is identified by a unique method name, which appears in the DID itself. For example, a DID with the method name “example” would look like “did:example:123456789abcdefghi”.
DID Web#
Affinidi sdk support did:web out of the box Specefication of methid could be found here https://w3c-ccg.github.io/did-method-web/. The idea behind - did document is published on well known address under a It is multiple pros amd cons for this method byt what i could say for sure it is widely adopted by community.
Pros
easy to scale
ledger and third paty system free
fast
feet well for enterprice and organisation that own web domains
close to Autononiomus identifiers (depends only on hosting with no third paty systems
Cons
main security mechanism here based on idea that website domain and DNS record is a main security protection. So you prove ownership of your public web site. it is not always safe on my opinion
domains could change an owner and be sold or reasigned
Lets create Wallet#
const { createWallet } = require('@affinidi/wallet-node-sdk')
import { EventComponent } from '@affinidi/wallet-core-sdk'
const walletFactory = createWallet(EventComponent.AffinidiCore)
const accessApiKey = '<your key>'
We should define in advance where we want to host our did web. Host name by default will expect that did is hosted on wellknown location did:web:volland.github.io: -> https://volland.github.io/.well-known/did.json if you have custom path it should be specified in a way did:web:volland.github.io:sdk-notebooks -> https://volland.github.io/sdk-notebooks/did.json
const options = {
env: 'prod',
accessApiKey: accessApiKey,
webDomain: 'volland.github.io:sdk-notebooks',
didMethod: 'web'
}
const wallet = await walletFactory.createWallet(options, 'P@ssw0rd')
wallet.didDocument
{
id: 'did:web:volland.github.io:sdk-notebooks',
'@context': 'https://w3id.org/security/v2',
publicKey: [
{
id: 'did:web:volland.github.io:sdk-notebooks#primary',
usage: 'signing',
type: 'Secp256k1VerificationKey2018',
publicKeyHex: '03b70a6116e9aae6666865c7a760fffc797e9ce6d91e57ae5f2c9ca4bc8e9a4d34'
},
{
id: 'did:web:volland.github.io:sdk-notebooks#recovery',
usage: 'recovery',
type: 'Secp256k1VerificationKey2018',
publicKeyHex: '029cd4cd2ff294a94fd194767e4a9c16d79a25ad80f10de8eb531cd7636fbd3f66'
}
],
authentication: [ 'did:web:volland.github.io:sdk-notebooks#primary' ],
assertionMethod: [ 'did:web:volland.github.io:sdk-notebooks#primary' ]
}
as you see wallet has property didDocument
that give us did document that we should host
We could backup in secured storage our encripted seed that will allow togenter with password unlock a wallet and sign a credentials with this did.
wallet.encryptedSeed
e2447a8368cc97a55be2d6f5e53da5f4714a0252dfc4b0999dc75dc384a1c2580e4a6abdc86d104403d547c5de823737511d6671399f1c7edff3fd00da1fd6581305a25e639f1d1a938e2dce89872c07b7ee507616385d5ed1862865e4edabfdc2a5b9ad1357474cb2afed573972b66151750c76e6a336d2e4190d1a27ecbf8648325f420337ec0c5a2b7d9d5c8b69ce88a5a5d8ad098f0b833a661ddc6ad5baf3b39f2eef9e9cfa7968447954ce5175b2314b88d5dbdaa3fd01ef4b4a5bdc64
Lets Host a did doc#
Just upload it to your domain. In our case i made a book publishing.
Lets Issue a VC#
You could do all operations with this did and wallet as with any other method
const jsonSchema = 'https://schema.affinidi.com/ContentLikeV1-0.json'
const jsonContext = 'https://schema.affinidi.com/ContentLikeV1-0.jsonld'
const id = `claimId:${(Math.random() + 1).toString(36).substring(2)}`
const unsignedVC = {
'@context': ['https://www.w3.org/2018/credentials/v1', jsonContext],
id,
type: ['VerifiableCredential', 'ContentLike'],
holder: {
id: wallet.did
},
credentialSubject: {
data: {
'@type': ['VerifiableCredential', 'ContentLike'],
url: 'https://www.youtube.com/watch?v=owbkzvLhblk',
date: new Date().toISOString(),
like: true,
score: 10
},
},
credentialSchema: {
id: jsonSchema,
type: 'JsonSchemaValidator2018',
},
issuanceDate: new Date().toISOString(),
expirationDate: '2065-09-10T00:00:00.000Z',
}
const signedVC = await wallet.signUnsignedCredential(unsignedVC)
JSON.stringify(signedVC, null,2)
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/ContentLikeV1-0.jsonld"
],
"id": "claimId:uv2kchuqy6",
"type": [
"VerifiableCredential",
"ContentLike"
],
"holder": {
"id": "did:web:volland.github.io:sdk-notebooks"
},
"credentialSubject": {
"data": {
"@type": [
"VerifiableCredential",
"ContentLike"
],
"url": "https://www.youtube.com/watch?v=owbkzvLhblk",
"date": "2023-04-06T15:05:58.830Z",
"like": true,
"score": 10
}
},
"credentialSchema": {
"id": "https://schema.affinidi.com/ContentLikeV1-0.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-04-06T15:05:58.830Z",
"expirationDate": "2065-09-10T00:00:00.000Z",
"issuer": "did:web:volland.github.io:sdk-notebooks",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-04-06T15:05:58Z",
"verificationMethod": "did:web:volland.github.io:sdk-notebooks#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..paG9PLEkUKiNeCtXpuOUylUWmnN5AAIxlo3iHrn8kIt1dp_mCcYV-gc4q4DVh2w1PPUF-g4ANMq1-zsD4bw_ag"
}
}
unknown msg_type: comm_open
unknown msg_type: comm_msg