本文目录导读:

在 PHP 中实现“自主身份”(Self-Sovereign Identity, SSI)并不是 PHP 本身内置的功能,而是需要结合密码学、去中心化标识符(DID)、可验证凭证(VC)以及区块链或分布式账本技术来构建的。
如果你是在问 “如何用PHP实现一套让用户自己控制、验证身份的自主身份系统”,核心逻辑通常涉及以下几个关键步骤和组件:
理解自主身份的核心要素
- 去中心化标识符(DID):用户创建的、由自己控制的唯一标识,不依赖中心化注册机构。
did:example:123456789abcdef。 - 公钥/私钥对:用户掌握私钥,用于签名和授权,公钥被写入 DID 文档中。
- 可验证凭证(VC):由发行方(如学校、政府)使用其私钥签名的数据(如“张三毕业于XX大学”),用户持有并选择性披露。
- 可验证呈现(VP):用户使用自己的私钥对已签名的 VC 进行再签名,再发送给验证方。
用 PHP 实现一个极简的自主身份框架(概念示例)
以下是一个极度简化的演示,展示核心的“自主控制”流程,实战中你需要更安全的密钥管理、DID 方法、分布式存储(如 IPFS)和区块链锚定。
步骤 1:生成 DID 和密钥对
使用 PHP 的 sodium 或 openssl 扩展。
<?php
// 生成一对 Ed25519 密钥(推荐用于 SSI)
$keypair = sodium_crypto_sign_keypair();
$secretKey = sodium_crypto_sign_secretkey($keypair);
$publicKey = sodium_crypto_sign_publickey($keypair);
$did = 'did:php:user:' . bin2hex($publicKey); // 简单粗暴的 DID 生成方式
// 存储密钥(生产环境严禁明文存储!)
file_put_contents('user_sk.key', $secretKey);
file_put_contents('user_pk.key', $publicKey);
echo "Your DID: $did\n";
echo "Public Key (hex): " . bin2hex($publicKey) . "\n";
步骤 2:创建 DID 文档(DID Document)
DID 文档描述了如何验证用户的公钥。
<?php
$publicKeyHex = bin2hex($publicKey);
$didDocument = [
'@context' => 'https://www.w3.org/ns/did/v1',
'id' => $did,
'verificationMethod' => [
[
'id' => $did . '#keys-1',
'type' => 'JsonWebKey2020',
'controller' => $did,
'publicKeyJwk' => [ // 将 Ed25519 公钥转为 JWK 格式
'kty' => 'OKP',
'crv' => 'Ed25519',
'x' => base64url_encode($publicKey)
]
]
],
'authentication' => [$did . '#keys-1'],
'assertionMethod' => [$did . '#keys-1']
];
// 通常此文档会存在 IPFS 或区块链上
echo json_encode($didDocument, JSON_PRETTY_PRINT);
步骤 3:签发可验证凭证(Issuer 操作)
假设你是“学校”角色,给学生“张三”签发一个毕业证凭证。
<?php
// 前提:学校有自己的DID和密钥
$credentialData = [
'@context' => ['https://www.w3.org/2018/credentials/v1'],
'type' => ['VerifiableCredential', 'UniversityDegreeCredential'],
'issuer' => $issuerDid,
'issuanceDate' => '2023-01-01',
'credentialSubject' => [
'id' => $studentDid, // 学生的 DID
'degree' => 'Bachelor of Computer Science'
]
];
// 学校用私钥对 credentialData 进行签名
$signature = sodium_crypto_sign_detached(
json_encode($credentialData),
$issuerSecretKey
);
$verifiableCredential = $credentialData;
$verifiableCredential['proof'] = [
'type' => 'Ed25519Signature2018',
'created' => '2023-01-01',
'verificationMethod' => $issuerDid . '#keys-1',
'proofValue' => base64url_encode($signature)
];
// 张三(用户)收到此凭证,存储在自己的钱包中
步骤 4:用户自主出示凭证(Holder -> Verifier)
张三想向某网站(验证方)证明自己毕业,但不需要透露学号等额外信息。
<?php
// 用户从钱包取出 VC 和 自己的私钥
$vc = json_decode(file_get_contents('my_credential.json'), true);
$mySecretKey = file_get_contents('user_sk.key');
// 构建可验证呈现(VP)
$presentation = [
'@context' => ['https://www.w3.org/2018/credentials/v1'],
'type' => ['VerifiablePresentation'],
'verifiableCredential' => [$vc], // 可以是一个或多个
'holder' => $myDid
];
// 用户用自己的私钥对这个呈现进行签名
$vpSignature = sodium_crypto_sign_detached(
json_encode($presentation),
$mySecretKey
);
$presentation['proof'] = [
'type' => 'Ed25519Signature2018',
'created' => '2023-06-01',
'verificationMethod' => $myDid . '#keys-1',
'proofValue' => base64url_encode($vpSignature)
];
// 发送这个 VP 给验证方
步骤 5:验证方验证(Verifier 操作)
验证方收到 VP 后,需要:
- 用用户的公钥验证 VP 的签名。
- 用学校的公钥验证 VC 的签名。
- 确认学校 DID 的公钥在链上/IResolve(SSI 解析器)中有效。
<?php
// 伪代码框架
function verifyPresentation($presentation, $didResolver) {
$holderDid = $presentation['holder'];
$userPublicKey = $didResolver->resolvePublicKey($holderDid);
// 1. 验证 VP 签名
$vpOk = sodium_crypto_sign_verify_detached(
base64url_decode($presentation['proof']['proofValue']),
json_encode($presentation['verifiableCredential']), // 数据部分
$userPublicKey
);
// 2. 验证每个 VC
foreach ($presentation['verifiableCredential'] as $vc) {
$issuerDid = $vc['issuer'];
$issuerPublicKey = $didResolver->resolvePublicKey($issuerDid);
$vcOk = sodium_crypto_sign_verify_detached(
base64url_decode($vc['proof']['proofValue']),
json_encode($vc['credentialSubject']),
$issuerPublicKey
);
}
return $vpOk && $vcOk;
}
PHP 实现 SSI 的实用库与框架
不要从零造轮子,使用现成的 PHP 库可以省去大量底层密码学工作:
web3php/ssi:一个专注于 DID 和 VC 的 PHP 库。scytale-io/php-did:处理 DID、DID Document 解析。php-libaum/did-kit:支持多种 DID 方法。Hyperledger Aries的 PHP 绑定:如果你要对接 Hyperledger 框架。
生产环境关键注意事项
- 密钥管理:绝对不能使用
file_put_contents存储密钥,必须使用 HSM(硬件安全模块) 或 KMS(如AWS KMS、HashiCorp Vault)。 - DID 方法:上面用的是伪方法,真实 SSI 需要采用
did:ion、did:key或did:ethr等标准方法,并在区块链上发布 DID 文档。 - 零知识证明:如果你需要“选择性披露”(如证明“我大于21岁”但不透露年龄),需要集成 BBS+ 签名等更复杂的密码学。
- 隐私与合规:自主身份涉及敏感数据,需遵守 GDPR 等法规。
- 互操作性:遵循 W3C 标准(DID、VC、VP)以确保不同系统间能互通。
PHP 能 实现自主身份,但核心挑战不在于语言(PHP 的 sodium 扩展已提供必要密码学能力),而在于:
- 安全的密钥管理
- 符合标准的 DID/VC 数据模型
- 分布式网络的集成(IPFS、区块链)
- 用户体验(用户如何管理私钥而不丢失)
如果你是初学者,建议先从 did:key 开始(最简单,不需要区块链存储),然后用 PHP 搭建一个本地 demo 来理解流程,等你熟悉后,再迁移到去中心化网络。