JS `Decentralized Identifiers` (DIDs) 与 `Verifiable Credentials` (VCs) 在 Web3 中的应用

嘿,大家好!今天咱们来聊聊 Web3 世界里的身份魔法:DIDs(Decentralized Identifiers,去中心化身份标识符)和 VCs(Verifiable Credentials,可验证凭证)。准备好了吗?咱们开始啦!

第一章:DIDs,你的 Web3 身份证

想象一下,在现实世界里,你有一张身份证,证明你是你。在 Web3 世界,DIDs 就扮演着类似的角色,只不过它更加自由、安全,而且完全由你掌控。

1.1 什么是 DID?

DID,简单来说,就是一个全球唯一的、可验证的标识符。它不依赖于任何中心化的机构,比如政府或者公司。你可以把它看作是一个指向你的数字身份信息的链接。

1.2 DID 的结构

一个典型的 DID 看起来像这样:

did:method:specific-id
  • did: 表示这是一个 DID。
  • method: 指定了 DID 使用的特定协议或方法。常见的 DID 方法包括 did:keydid:pkh (Public Key Hash)、did:web 等。
  • specific-id: 是一个根据所选方法定义的唯一标识符。

举个例子:

did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u

这个 DID 使用了 did:key 方法,意味着它的标识符是基于公钥生成的。

1.3 DID 的工作原理

DIDs 的核心在于去中心化身份注册表(DID Registry)。这个注册表通常是一个区块链或者分布式账本,用于存储 DID 文档(DID Document)。

DID 文档包含了关于 DID 的各种信息,比如:

  • 公钥:用于验证 DID 控制者的身份。
  • 服务端点:指向与 DID 相关的服务,比如消息传递或者数据存储。
  • 验证方法:指定用于验证身份的方法。

1.4 使用 JavaScript 创建 DID

我们可以使用一些 JavaScript 库来创建和管理 DIDs。这里我们以 did-key.js 为例:

import { Ed25519Provider } from 'key-did-provider-ed25519'
import { DID } from 'dids'
import { randomBytes } from 'crypto'

async function createDidKey() {
  // 1. 创建一个 Ed25519 密钥对
  const seed = randomBytes(32)
  const provider = new Ed25519Provider(seed)

  // 2. 初始化 DID
  const did = new DID({ provider })

  // 3. 解析 DID 文档
  await did.authenticate()

  // 4. 打印 DID
  console.log('你的 DID:', did.id)
  console.log('DID 文档:', did.document)

  return did.id;
}

createDidKey();

这段代码做了什么?

  1. 我们引入了必要的库:key-did-provider-ed25519 用于生成 Ed25519 密钥对,dids 用于管理 DID。
  2. 我们生成了一个随机的 32 字节的种子,用于创建 Ed25519 密钥对。
  3. 我们使用 Ed25519Provider 创建了一个 DID provider。
  4. 我们使用 DID provider 初始化了一个 DID 实例。
  5. 我们调用 did.authenticate() 来解析 DID 文档。
  6. 我们打印了 DID 和 DID 文档。

运行这段代码,你会得到一个类似这样的 DID:

did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u

以及一个 DID 文档,其中包含了你的公钥和其他相关信息。

第二章:VCs,可验证的数字凭证

现在你有了 Web3 身份证 (DID),接下来你需要一些凭证来证明你的身份或者资格。这就是 VCs 的用武之地。

2.1 什么是 VC?

VC,全称 Verifiable Credential,是一种数字化的凭证,可以用来证明某个实体(人、组织、设备等)的特定属性。它可以类比于现实世界中的学历证书、驾驶执照、会员卡等等。

2.2 VC 的结构

一个典型的 VC 包含以下几个部分:

  • @context: 定义了 VC 使用的词汇表和数据模型。
  • type: 指定了 VC 的类型,比如 VerifiableCredentialAlumniCredential 等。
  • issuer: 发行 VC 的 DID。
  • issuanceDate: VC 的发行日期。
  • credentialSubject: 描述 VC 声明的主题,比如你的姓名、年龄、学历等。
  • proof: 用于验证 VC 的有效性的数字签名。

2.3 VC 的工作原理

VC 的发行者使用自己的私钥对 VC 进行签名,生成一个数字签名,并将其包含在 VC 的 proof 字段中。验证者可以使用发行者的公钥来验证 VC 的签名是否有效,从而确认 VC 的真实性和完整性。

2.4 使用 JavaScript 创建 VC

我们可以使用一些 JavaScript 库来创建和验证 VCs。这里我们以 vc-js 为例:

import { createVerifiableCredentialJwt, verifyCredential } from 'vc-jwt'
import { Ed25519Provider } from 'key-did-provider-ed25519'
import { DID } from 'dids'
import { randomBytes } from 'crypto'

async function createAndVerifyVC() {
  // 1. 创建发行者 DID
  const issuerSeed = randomBytes(32)
  const issuerProvider = new Ed25519Provider(issuerSeed)
  const issuerDid = new DID({ provider: issuerProvider })
  await issuerDid.authenticate()

  // 2. 创建被颁发者 DID (Credential Subject)
  const subjectSeed = randomBytes(32)
  const subjectProvider = new Ed25519Provider(subjectSeed)
  const subjectDid = new DID({ provider: subjectProvider })
  await subjectDid.authenticate()

  // 3. 定义 VC 的内容
  const credentialSubject = {
    id: subjectDid.id,
    name: '张三',
    age: 30,
    university: '清华大学'
  };

  // 4. 创建 VC
  const vc = await createVerifiableCredentialJwt({
    type: ['VerifiableCredential', 'AlumniCredential'],
    issuer: issuerDid.id,
    subject: credentialSubject,
    expirationDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString() // 一年后过期
  }, { did: issuerDid, alg: 'EdDSA' })

  console.log('创建的 VC:', vc)

  // 5. 验证 VC
  const verificationResult = await verifyCredential(vc, issuerDid.resolver.resolve)

  console.log('VC 验证结果:', verificationResult.verified)

  return vc;
}

createAndVerifyVC();

这段代码做了什么?

  1. 我们创建了发行者 DID 和被颁发者 DID。
  2. 我们定义了 VC 的内容,包括被颁发者的姓名、年龄和大学。
  3. 我们使用 createVerifiableCredentialJwt 函数创建了一个 VC,并使用发行者的私钥对其进行签名。
  4. 我们使用 verifyCredential 函数验证 VC 的有效性,并使用发行者的公钥来验证签名。

运行这段代码,你会得到一个 JWT 格式的 VC,以及验证结果,告诉你 VC 是否有效。

第三章:DIDs 和 VCs 在 Web3 中的应用场景

DIDs 和 VCs 为 Web3 带来了无限的可能性。以下是一些常见的应用场景:

  • 去中心化身份验证: 用户可以使用 DID 来登录各种 Web3 应用,无需依赖中心化的身份提供商。
  • 可验证的数据共享: 用户可以使用 VC 来证明自己的身份或者资格,从而安全地共享数据。
  • 供应链管理: 可以使用 VC 来追踪商品的来源和流向,确保商品的质量和安全。
  • 医疗保健: 患者可以使用 VC 来管理自己的医疗记录,并授权给医生或者其他医疗机构访问。
  • 教育: 学生可以使用 VC 来证明自己的学历和技能,方便求职或者升学。

3.1 应用场景表格

应用场景 描述 优势
去中心化身份验证 使用 DID 登录 Web3 应用 无需中心化身份提供商,用户掌控自己的身份信息,防止数据泄露和滥用。
可验证的数据共享 使用 VC 证明身份或资格,安全地共享数据 数据共享更加安全可控,用户可以精确控制谁可以访问自己的数据,以及访问哪些数据。
供应链管理 使用 VC 追踪商品来源和流向 提高供应链的透明度和可追溯性,确保商品的质量和安全,防止假冒伪劣商品。
医疗保健 使用 VC 管理医疗记录,授权访问 患者可以更好地掌控自己的医疗记录,保护个人隐私,方便医生获取患者的病史信息,提高诊疗效率。
教育 使用 VC 证明学历和技能 方便学生求职或升学,雇主或学校可以快速验证学生的学历和技能,减少人为因素干扰,提高招聘效率。
Web3社交媒体 使用 DID 构建去中心化社交身份,拥有自己的数据所有权 用户拥有自己的社交数据,防止平台滥用用户数据,构建更加开放和公平的社交网络。
去中心化金融(DeFi) 使用 VC 进行 KYC/AML 验证,合规参与 DeFi 应用 简化 KYC/AML 流程,提高用户体验,降低合规成本,促进 DeFi 生态的健康发展。
物联网(IoT) 使用 DID 作为设备的身份标识,保证设备间的安全通信 提高物联网设备的安全性,防止恶意攻击和数据篡改,构建更加安全可靠的物联网生态系统。

第四章:DIDs 和 VCs 的挑战与未来

虽然 DIDs 和 VCs 带来了很多好处,但它们也面临着一些挑战:

  • 互操作性: 不同的 DID 方法和 VC 数据模型之间可能存在不兼容性,导致无法互操作。
  • 用户体验: DIDs 和 VCs 的使用对于普通用户来说可能比较复杂,需要更好的用户体验。
  • 隐私保护: 虽然 DIDs 和 VCs 可以提高隐私保护,但也需要注意防止数据泄露和滥用。
  • 标准化: 需要制定统一的 DID 和 VC 标准,以促进其广泛应用。

未来,我们可以期待 DIDs 和 VCs 在 Web3 中发挥更大的作用。随着技术的不断发展和标准的不断完善,它们将为我们带来更加安全、自由和可信的数字身份体验。

第五章:代码示例:一个简单的 DID/VC 交互示例

为了更清晰地展示 DIDs 和 VCs 的交互过程,我们创建一个简单的示例,模拟用户使用 VC 登录 Web3 应用的场景。

// 假设我们已经有了用户的 DID 和 VC (前面章节创建的)

async function loginWithVC(userDid, vc, verifierDidResolver) {
  // 1. 验证 VC 的有效性
  const verificationResult = await verifyCredential(vc, verifierDidResolver);

  if (!verificationResult.verified) {
    console.error('VC 验证失败!');
    return false;
  }

  // 2. 从 VC 中提取用户信息
  const credentialSubject = vc.payload.vc.credentialSubject;
  const userName = credentialSubject.name;

  // 3. 使用 DID 和用户信息登录应用
  console.log(`用户 ${userName} (DID: ${userDid}) 成功登录应用!`);
  return true;
}

// 模拟 Web3 应用的 DID resolver
const appDidResolver = {
    resolve: async (did) => {
        // 假设这里从某个地方(如数据库或 DID Registry)获取 DID 文档
        // 这里只是一个简单的示例,实际应用中需要更完善的逻辑
        if (did === 'did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u') {
            return {
                didDocument: {
                    id: 'did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u',
                    verificationMethod: [
                        {
                            id: 'did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u#controller',
                            type: 'Ed25519VerificationKey2018',
                            controller: 'did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u',
                            publicKeyMultibase: 'z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u' // 替换为实际公钥
                        }
                    ]
                }
            };
        }
        return null;
    }
};

// 使用示例
async function example() {
    // 假设这是用户的 DID 和 VC (从前面的代码示例中获取)
    const userDid = 'did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u'; // 替换为实际 DID
    const vc = { // 替换为实际 VC
        "@context": [
            "https://www.w3.org/2018/credentials/v1"
        ],
        "type": [
            "VerifiableCredential",
            "AlumniCredential"
        ],
        "issuer": "did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u", // 替换为实际 Issuer DID
        "issuanceDate": "2023-10-27T10:00:00Z",
        "credentialSubject": {
            "id": userDid,
            "name": "张三",
            "age": 30,
            "university": "清华大学"
        },
        "proof": {
            "type": "Ed25519Signature2018",
            "created": "2023-10-27T10:00:00Z",
            "jws": "eyJhbGciOiJFZERTQSJ9.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiQWx1bW5pQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6a2V5Ono2TWtwVEhSM2RvZ2pYOUZqbWN3WTRyZTFqNWJManBta0VmY0o1MkZORFBYNHUiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTEwLTI3VDEwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6Nk1rcFRIUjNkb2dqWDlGam1jdzlScGUxajViTGptcGtFZmMKNjJGTkRQWDV1IiwibmFtZSI6IuWwj-eoiSIsImFnZSI6MzAsInVuaXZlcnNpdHkiOiLnlLXlvbHlnLDlj7wiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTAtMjdUMTA6MDA6MDBaIn19.dGVzdA", // 替换为实际签名
            "proofPurpose": "assertionMethod",
            "verificationMethod": "did:key:z6MkpTHR3dogjX9FjmcwY4re1j5bLjmpkEfcJ52FNDPX4u#controller"  // 替换为实际验证方法
        }
    };

    const success = await loginWithVC(userDid, vc, appDidResolver.resolve);

    if (success) {
        console.log('登录成功!');
    } else {
        console.log('登录失败!');
    }
}

example();

代码解释:

  1. loginWithVC 函数模拟了使用 VC 登录 Web3 应用的过程。
  2. 它首先验证 VC 的有效性,确保 VC 没有被篡改或者过期。
  3. 然后,它从 VC 中提取用户信息,比如用户的姓名。
  4. 最后,它使用 DID 和用户信息登录应用。
  5. appDidResolver 模拟了一个简单的 DID resolver,用于解析 Web3 应用的 DID 文档。在实际应用中,你需要使用更完善的 DID resolver,比如从 DID Registry 中获取 DID 文档。
  6. example 函数模拟了整个登录过程。它首先定义了用户的 DID 和 VC,然后调用 loginWithVC 函数进行登录。

注意:

  • 这只是一个简单的示例,实际应用中需要更完善的逻辑。
  • 你需要替换代码中的 DID 和 VC 为你自己的 DID 和 VC。
  • 你需要使用更完善的 DID resolver 来解析 DID 文档。
  • 你需要根据实际应用场景修改代码。

第六章:总结

今天我们一起探索了 Web3 世界里的身份魔法:DIDs 和 VCs。我们学习了 DIDs 的结构和工作原理,以及如何使用 JavaScript 创建 DID。我们还学习了 VCs 的结构和工作原理,以及如何使用 JavaScript 创建和验证 VC。最后,我们讨论了 DIDs 和 VCs 在 Web3 中的应用场景和挑战,并展望了它们的未来。

希望今天的讲座能帮助你更好地理解 DIDs 和 VCs,并为你在 Web3 世界里构建更加安全、自由和可信的应用提供一些启发。

好了,今天的讲座就到这里,谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注