深圳市网站建设_网站建设公司_前后端分离_seo优化
2026/1/19 16:04:07 网站建设 项目流程

第一章:为什么需要可验证网络?

1.1 传统身份系统的缺陷

问题说明
  • 中心化风险| 平台掌握用户身份,可滥用或被攻破(如 Facebook 数据泄露)
  • 重复 KYC| 每个新服务都要重新提交身份证、住址等
  • 信息过曝| 验证年龄需提交完整出生日期

1.2 可验证网络三要素(W3C 标准)

  1. DID(去中心化标识符)
    • 格式:did:example:123456abcdef
    • 特性:用户创建、用户控制、无需注册机构
    • 存储:区块链 / IPFS / 去中心化存储
  2. VC(可验证凭证)
    • Issuer(发行方)签发(如政府、银行)
    • 包含Claims(声明)+Issuer 签名
    • 示例:
{ "@context": ["https://www.w3.org/2018/credentials/v1"], "type": ["VerifiableCredential", "AgeCredential"], "issuer": "did:example:gov123", "issuanceDate": "2025-01-01T00:00:00Z", "credentialSubject": { "id": "did:example:user456", "birthDate": "2000-05-20" }, "proof": { /* 签名 */ } }
  1. VP(可验证陈述)
    • 用户从多个 VC 中选择性披露信息
    • 可附加零知识证明实现最小化披露

信任模型转变
“相信平台”“验证密码学证明”


第二章:架构设计 —— DID + ZKP 全栈集成

2.1 整体流程(无密码登录)

[Vue 前端] │ ├── 1. 生成挑战(nonce) ←── [Flask 后端] │ ├── 2. 用户钱包签名 nonce + DID │ (或生成 ZK 证明) │ └── 3. 提交 VP → [Flask 验证] → 登录成功

2.2 技术栈选型

功能技术说明
  • DID 管理|ethr-did(以太坊兼容) | 支持 EVM 链
  • VC 签发/验证|veramo(JavaScript SDK) | W3C 兼容
  • ZK 电路| Circom + SnarkJS | 浏览器友好
  • 钱包连接| WalletConnect v2 | 支持多钱包
  • 后端验证| Pythonpy_did+ 自定义 ZK 验证器 |

第三章:无密码登录 —— DID 签名认证

3.1 后端:生成挑战

# routes/auth.py from flask import session import secrets @app.route('/auth/challenge') def get_challenge(): challenge = secrets.token_urlsafe(32) session['challenge'] = challenge return jsonify({"challenge": challenge})

3.2 前端:钱包签名

<script setup> import { EthereumProvider } from '@walletconnect/ethereum-provider' const connectWallet = async () => { const provider = await EthereumProvider.init({ projectId: 'YOUR_WALLETCONNECT_ID', chains: [1], methods: ['eth_requestAccounts', 'personal_sign'] }) await provider.enable() window.ethereum = provider } const loginWithDID = async () => { // 1. 获取挑战 const res = await fetch('/auth/challenge') const { challenge } = await res.json() // 2. 获取用户地址(作为 DID) const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }) const did = `did:pkh:eip155:1:${accounts[0].toLowerCase()}` // 3. 签名挑战 const signature = await window.ethereum.request({ method: 'personal_sign', params: [challenge, accounts[0]] }) // 4. 提交 VP await fetch('/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ did, challenge, signature }) }) } </script>

3.3 后端:验证签名

# utils/did_auth.py from ecdsa import VerifyingKey, SECP256k1 import sha3 from eth_utils import to_checksum_address def verify_did_signature(did: str, challenge: str, signature: str) -> bool: # 1. 从 DID 提取地址 if not did.startswith('did:pkh:eip155:1:'): return False address = to_checksum_address('0x' + did.split(':')[-1]) # 2. 构造签名消息(EIP-191) message = f"\x19Ethereum Signed Message:\n{len(challenge)}{challenge}" message_hash = sha3.keccak_256(message.encode()).digest() # 3. 恢复公钥 sig = bytes.fromhex(signature[2:]) # 去掉 0x vk = VerifyingKey.from_signature( sig[:-1], # 去掉恢复 ID message_hash, curve=SECP256k1, hashfunc=sha3.keccak_256 ) recovered_addr = to_checksum_address(vk.to_string('compressed')[1:]) return recovered_addr == address

优势

  • 无密码、无 OAuth 依赖
  • 用户用已有钱包即可登录

第四章:零知识证明实战 —— 年龄验证

4.1 问题定义

用户想证明自己 ≥18 岁,但不想透露具体生日。

4.2 ZK 电路设计(Circom)

// circuits/age_check.circom pragma circom 2.0.0; template AgeCheck() { signal input birthYear; // 用户私有输入 signal input currentYear; // 公共输入 signal output isAdult; // 公共输出 signal diff; diff <== currentYear - birthYear; isAdult <== diff >= 18 ? 1 : 0; } component main = AgeCheck();

4.3 编译与生成证明(前端)

# 编译电路 circom age_check.circom --r1cs --wasm --sym # 启动 SnarkJS 服务(用于可信设置) snarkjs groth16 setup age_check.r1cs pot17_final.ptau age_check_0000.zkey

4.4 浏览器中生成证明

// zk/age_prover.ts import { groth16 } from 'snarkjs' import ageCheckWasm from './age_check.wasm?url' import zkey from './age_check_0000.zkey?url' export async function generateAgeProof(birthYear: number, currentYear: number = 2025) { const { proof, publicSignals } = await groth16.fullProve( { birthYear, currentYear }, ageCheckWasm, zkey ) return { proof, publicSignals // [isAdult (0/1), currentYear] } }

4.5 后端验证证明

# utils/zk_verifier.py import json from py_ecc.bn128 import bn128_curve as curve from snarkjs import groth16_verify # 假设有 Python 绑定 def verify_age_proof(proof_json: dict, public_signals: list) -> bool: with open('verification_key.json') as f: vkey = json.load(f) return groth16_verify(vkey, public_signals, proof_json)

隐私保障

  • 后端只知道isAdult=1,不知道birthYear=2000
  • 证明不可伪造(基于椭圆曲线密码学)

第五章:可验证凭证(VC)系统

5.1 发行 VC(银行 KYC 场景)

# services/vc_issuer.py from veramo import create_verifiable_credential def issue_kyc_vc(user_did: str, name: str, birth_date: str): credential = { "@context": ["https://www.w3.org/2018/credentials/v1"], "type": ["VerifiableCredential", "KYCCredential"], "issuer": BANK_DID, "issuanceDate": datetime.utcnow().isoformat() + "Z", "credentialSubject": { "id": user_did, "name": name, "birthDate": birth_date } } return create_verifiable_credential(credential, issuer_private_key)

5.2 用户存储 VC

  • 数字钱包(如 Polygon ID Wallet)安全存储 VC
  • VC 不上链:仅 DID 文档和状态(如撤销)上链

5.3 验证 VC(第三方平台)

# routes/verify_kyc.py from veramo import verify_credential @app.route('/verify/kyc', methods=['POST']) def verify_kyc(): vp = request.json # Verifiable Presentation # 1. 验证 VC 签名 if not verify_credential(vp['verifiableCredential']): return jsonify({"error": "Invalid VC"}), 400 # 2. 检查 DID 是否在许可列表 if vp['holder']['id'] not in allowed_dids: return jsonify({"error": "Unauthorized"}), 403 return jsonify({"status": "verified"})

优势

  • 用户一次 KYC,多处复用
  • 平台无需存储敏感个人信息

第六章:前端集成 —— Vue + WalletConnect

6.1 封装 DID 登录组件

<template> <button @click="login" :disabled="loading"> {{ loading ? 'Connecting...' : 'Login with Wallet' }} </button> </template> <script setup> import { useDIDAuth } from '@/composables/didAuth' const { login, loading } = useDIDAuth() </script>

6.2 Composable 逻辑

// composables/didAuth.ts import { ref } from 'vue' export function useDIDAuth() { const loading = ref(false) const login = async () => { loading.value = true try { await connectWallet() const { challenge } = await fetchChallenge() const { did, signature } = await signChallenge(challenge) await submitVP({ did, challenge, signature }) // 登录成功,跳转 router.push('/dashboard') } finally { loading.value = false } } return { login, loading } }

用户体验:与传统“微信登录”按钮无异,但更安全、更隐私。


第七章:隐私与安全最佳实践

7.1 防重放攻击

  • 挑战(nonce)一次性+短期有效(如 5 分钟)
  • VP 中包含有效期唯一 ID

7.2 凭证撤销

  • 使用Status List 2021(W3C 标准)
  • 撤销列表存储于 IPFS,DID 文档指向最新列表

7.3 最小化披露原则

  • 默认使用ZK 证明而非原始 VC
  • 前端明确告知用户“将披露哪些信息”

第八章:性能与兼容性

8.1 ZK 证明生成时间

设备电路复杂度生成时间
  • 现代笔记本| AgeCheck(简单) | ~800ms
  • iPhone 14| 同上 | ~1.2s
  • 低端安卓| 同上 | ~2.5s

优化

  • 预加载 WASM 模块
  • 使用 Web Worker 避免阻塞 UI

8.2 钱包兼容性

钱包DID 支持VC 支持
  • MetaMask| ✅ (via Snap) | ❌
  • Polygon ID Wallet| ✅ | ✅
  • Microsoft Entra Verified ID| ✅ | ✅

策略:优先支持 Polygon ID,降级到 DID 签名。


第九章:合规与伦理

9.1 GDPR 合规

  • 用户可删除 VC:钱包本地删除,平台仅保留验证记录(无 PII)
  • 数据最小化:ZK 证明天然符合

9.2 防止歧视

  • 避免生物特征 VC:如种族、基因等敏感属性
  • 开源验证逻辑:防止隐藏偏见算法

第十章:未来方向

10.1 BBS+ 签名

  • 支持选择性披露而无需 ZK(如只出示 VC 中的“年龄”字段)
  • 工具:@mattrglobal/bbs-signatures

10.2 跨链 DID

  • 使用ENS + .eth 域名作为人类可读 DID
  • 示例:did:pkh:eip155:1:0x...alice.eth

总结:构建用户主权的身份层

可验证网络不是加密乌托邦,而是下一代互联网信任基础设施。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询