核心概念 / 入门 / 10 分钟

可验证凭证

任何人都可以验证的密码学声明——无需回调签发者

可验证凭证要解决的问题

如今的凭证验证都需要验证者回调签发者:

  • 学位证书 —— 雇主打电话给大学:“Alice 真的毕业了吗?”
  • 在职证明 —— 房东打电话给公司:“Bob 真的在那里工作吗?”
  • 智能体授权 —— 合作伙伴调用你的系统:“Agent-42 是否被允许执行此操作?”

存在的问题:

  • 隐私泄露 —— 签发者会得知是谁在验证、何时验证
  • 依赖性 —— 若签发者的系统宕机,验证者就无法完成验证
  • 延迟 —— 实时验证需要发起 API 调用
  • 吊销检查 —— 每次都必须向签发者核实状态

可验证凭证(VC) 解决了这个问题:一种经过密码学签名的声明,任何人都可以验证,而无需联系签发者。


什么是可验证凭证?

VC 是由一方(签发者)针对另一方(持有者)签发的、经过数字签名的声明。

示例:大学向 Alice 签发学位证书

{
  "@context": ["https://www.w3.org/2018/credentials/v1"],
  "type": ["VerifiableCredential", "UniversityDegreeCredential"],
  "issuer": "did:webvh:stanford.edu",
  "issuanceDate": "2024-06-15T00:00:00Z",
  "credentialSubject": {
    "id": "did:webvh:alice.com",
    "degree": {
      "type": "BachelorDegree",
      "name": "Bachelor of Science in Computer Science"
    }
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2024-06-15T00:00:00Z",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:webvh:stanford.edu#key-1",
    "proofValue": "z3FXQi...signature..."
  }
}

关键属性:

  1. 签发者 —— 谁做出了这个声明(斯坦福大学)
  2. 持有者 —— 声明是关于谁的(Alice)
  3. 声明内容 —— 所主张的内容(获得的学位)
  4. 证明 —— 来自签发者的密码学签名
  5. 可验证 —— 任何人都能在不联系斯坦福大学的情况下验证签名

可验证凭证的工作原理

1. 签发

签发者对凭证进行签名:

// 签发者 (斯坦福大学) 为 Alice 创建凭证
const credential = {
  issuer: 'did:webvh:stanford.edu',
  credentialSubject: {
    id: 'did:webvh:alice.com',
    degree: { type: 'BachelorDegree', name: 'Computer Science' }
  },
  issuanceDate: new Date().toISOString()
}

// 用签发者的私钥签名
const signedVC = await sign(credential, issuerPrivateKey)

// Alice 存储它 (存入钱包、数据库等)

2. 出示

持有者共享该凭证:

// Alice 向雇主出示该 VC
const presentation = {
  type: 'VerifiablePresentation',
  holder: 'did:webvh:alice.com',
  verifiableCredential: [signedVC],
  proof: { /* Alice 的签名,证明她控制该 DID */ }
}

3. 验证

验证者检查凭证:

// 雇主验证:
// 1. 签发者的签名是否有效
const issuerDID = presentation.verifiableCredential[0].issuer
const issuerKey = await resolve(issuerDID) // 获取斯坦福大学的公钥
const isValidSignature = await verify(signedVC, issuerKey)

// 2. 持有者是否控制该 DID (Alice 对出示内容进行了签名)
const holderKey = await resolve(presentation.holder)
const isValidPresentation = await verify(presentation.proof, holderKey)

// 3. 凭证是否已被吊销 (可选,检查状态列表)
const isRevoked = await checkRevocation(signedVC)

// ✅ 所有检查通过 — 凭证有效

无需回调斯坦福大学!


可验证凭证与传统凭证的对比

维度传统方式 (例如 API 调用)可验证凭证
验证方式调用签发者的 API在本地验证签名
隐私性签发者能看到每一次验证签发后签发者不再获知任何信息
可用性签发者宕机则验证失败可离线工作
延迟需要网络往返即时 (本地验证)
选择性披露全有或全无只共享所需的部分
吊销每次都要向签发者核实检查状态列表 (可缓存)

真实应用场景

1. 智能体授权 Mandate

问题: A 银行的智能体需要证明自己被授权进行交易。B 银行必须实时验证。

解决方案: A 银行向该智能体签发一份 VC(Mandate)。B 银行验证签名,无需回调 A 银行。

{
  "type": ["VerifiableCredential", "TradingMandate"],
  "issuer": "did:webvh:bankA.com",
  "credentialSubject": {
    "id": "did:webvh:bankA.com:agent-42",
    "mandate": {
      "authorizedBy": "did:webvh:bankA.com:trader-alice",
      "permissions": ["execute-trades"],
      "expiry": "2026-12-31"
    }
  },
  "proof": { "proofValue": "z3FXQi..." }
}

B 银行的验证过程:

// 1. 检查 A 银行的签名 (这真的是 A 银行签发的吗?)
const isValid = await verifyCredential(mandate)

// 2. 检查是否过期 (是否仍然有效?)
const isExpired = new Date() > new Date(mandate.credentialSubject.mandate.expiry)

// 3. 检查吊销状态 (A 银行是否吊销了它?)
const isRevoked = await checkRevocation(mandate)

// ✅ 验证通过——无需调用 A 银行的 API

2. PHI 访问授权

问题: AI 智能体需要证明某位个案管理员已授权其访问 PHI——HIPAA 要求提供证明。

解决方案: 签发一份将智能体与个案管理员关联起来的 VC。审计日志捕获该 VC——证明是密码学层面的,而不仅仅是一条日志记录。

{
  "type": ["VerifiableCredential", "PHIAccessAuthorization"],
  "issuer": "did:webvh:hospital.com",
  "credentialSubject": {
    "id": "did:webvh:hospital.com:agent-99",
    "authorization": {
      "authorizedBy": "did:webvh:hospital.com:caseworker-bob",
      "patient": "patient-12345",
      "purpose": "treatment-review",
      "expiry": "2026-07-22T00:00:00Z"
    }
  },
  "proof": { "proofValue": "..." }
}

审计追踪:

// 日志条目
{
  timestamp: '2026-07-21T19:30:00Z',
  action: 'access-PHI',
  agent: 'did:webvh:hospital.com:agent-99',
  authorization: vcAsJson, // 完整的 VC
  verifiedBy: 'gateway-node-5'
}

// 数月后,审计员依然可以验证该 VC 的签名——仍然有效

3. 选择性披露(年龄验证)

问题: 证明你年满 21 岁,而不透露你的出生日期。

解决方案: 使用 BBS+ 签名 的 VC 可以在不透露完整声明的情况下证明某项属性。

// 已签发的 VC (完整声明)
const vc = {
  credentialSubject: {
    name: 'Alice',
    birthdate: '1995-03-15',
    address: '123 Main St'
  }
}

// 选择性披露——证明年龄 > 21 而不透露出生日期
const derivedVC = await deriveCredential(vc, {
  reveal: ['over21: true'], // 只披露这一项
  hide: ['name', 'birthdate', 'address'] // 隐藏其余全部信息
})

// 验证者看到:
{
  credentialSubject: {
    over21: true // 已通过密码学方式证明,不会透露其他任何数据
  }
}

吊销机制:Status List 2021

问题: 一份已经流通在外的 VC,该如何吊销?

解决方案: Status List 2021 —— 一个由签发者托管的位串(bitstring)。每份 VC 都指向其中的一个比特位:

{
  "credentialStatus": {
    "id": "https://issuer.com/status/42#94567",
    "type": "StatusList2021Entry",
    "statusPurpose": "revocation",
    "statusListIndex": "94567",
    "statusListCredential": "https://issuer.com/status/42"
  }
}

验证:

// 1. 获取状态列表 (可缓存)
const statusList = await fetch('https://issuer.com/status/42')

// 2. 检查第 94567 位
const isRevoked = statusList.bitstring[94567] === 1

// ✅ 若为 0 → 有效,若为 1 → 已吊销

隐私保护: 验证者能得知”这份凭证是否已被吊销?“,但签发者无法得知是谁查询的。


Affinidi 技术栈中的可验证凭证

Elements Services 负责签发 VC:

const vc = await elements.issueCredential({
  holder: 'did:webvh:agent-42.com',
  type: 'TradingMandate',
  claims: {
    authorizedBy: 'trader-alice',
    permissions: ['execute-trades'],
    expiry: '2026-12-31'
  }
})

Agent Gateway 在允许操作前验证 VC:

// 智能体携带 VC 提出请求
const request = {
  action: 'execute-trade',
  credential: vcAsJson
}

// Gateway 进行验证
const isValid = await agentGateway.verifyCredential(request.credential)
if (!isValid) throw new Error('未获授权')

// 若有效则继续执行

信任注册表 存储吊销状态:

// 检查 VC 是否已被吊销
const isRevoked = await trustRegistry.checkRevocation({
  credentialId: 'urn:uuid:abc-123',
  statusListUrl: 'https://issuer.com/status/42'
})

快速上手

面向开发者

签发一份可验证凭证:

npm install @affinidi/affinidi-tdk
import { VC } from '@affinidi/affinidi-tdk'

const credential = await VC.issue({
  issuer: 'did:webvh:yourcompany.com',
  holder: 'did:webvh:agent-42.com',
  type: 'EmploymentCredential',
  claims: {
    position: 'Trading Agent',
    authorizedBy: 'manager@yourcompany.com',
    startDate: '2026-01-01'
  }
})

console.log(credential) // 已签名的 VC,可供共享

验证一份凭证:

const isValid = await VC.verify(credential)
console.log(isValid) // true/false

面向架构师

何时应使用 VC:

  • ✅ 需要在离线情况下依然有效的授权证明
  • ✅ 无需共享基础设施的跨组织信任
  • ✅ 隐私保护型验证
  • ✅ 带密码学证明的审计追踪

何时不应使用 VC:

  • ❌ 高频更新的场景(VC 是一次性签发的,需要更新时应重新签发)
  • ❌ 实时流式数据
  • ❌ 使用 API 调用就足够的内部系统

延伸阅读

W3C 规范:

Affinidi 文档:

相关深度解析:

相关解决方案:

Cookie Preferences

We use cookies to enhance your experience. You can manage your preferences below. For more information, read our Cookie Policy.

Strictly Necessary Always Active

These cookies are essential for core website functions such as security, session integrity, and cookie preference storage. They cannot be disabled.

  • _cf_bm: Distinguishes humans from bots (Cloudflare) · 30m
  • _cfuvid: Ensures secure browsing (Cloudflare) · Session
  • __hs_initial_opt_in: Prevents HubSpot's banner · 7 days
  • _gtm_debug: GTM debug mode (testing only) · Session
Analytics

These cookies help us understand how visitors interact with the site so we can improve content and performance. All data is aggregated and anonymous.

  • _ga, _gid, _gat: Google Analytics · Session – 2 years
  • __hstc, hubspotutk, __hssrc: HubSpot visitor tracking · 13 months
  • __hs_opt_out: HubSpot opt-out preference · 6 months
Marketing & Targeting

These cookies allow us and our partners to serve personalised ads and measure campaign performance.

  • _gcl_au, _gcl_dc: Google Ads conversion tracking · 90 days
  • IDE: Google Display Network personalisation · 1 year
  • _fbp: Meta / Facebook remarketing · 90 days
  • li_gc, _li_fat_id, bcookie: LinkedIn tracking · 1–24 months
  • guest_id, personalization_id: Twitter/X analytics · 2 years