上期我们为大家介绍了 Blockerts 作为可验证凭证是如何实现的,本期我们将继续连载翻译 Rebooting Web of Trust 组织在 RWOT IX — Prague, 2019会议上的论文《Blockcerts V3 Proposal》,介绍 Blockerts V3 的一些示例及相关讨论。
原文:
https://github.com/WebOfTrustInfo/rwot9-prague/blob/master/final-documents/BlockcertsV3.md
作者:
Anthony Ronning,Wong Wai Chung
1. Blockcerts V3 的示例
凭证:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/blockcerts/v3"
],
"id": "urn:uuid:bbba8553-8ec1-445f-82c9-a57251dd731c",
"type": ["VerifiableCredential", "BlockcertsCredential"],
"issuer": "did:example:23adb1f712ebc6f1c276eba4dfa",
"issuanceDate": "2010-01-01T19:73:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"holds": {
"id": "https://example.com/badgeclasses/123",
"type": "BadgeClass",
"name": "Certificate of Accomplishment",
"image": "data:image/png;base64,...",
"description": "A badge describing great accomplishments",
"criteria": {
"narrative": "Perform tasks of valor and wit."
},
"issuer": {
"type": "Profile",
"id": "did:example:23adb1f712ebc6f1c276eba4dfa",
"name": "Example Issuer",
"url": "http://example.com",
"email": "test@example.com"
}
}
},
"evidence": {
"id": "https://example.org/portfolios/25",
"name": "Bob's Portfolio",
"narrative": "Bob worked hard to develop a good portfolio",
"genre": "ePortfolio"
},
"metadata": {
"type": "json",
"data": "{\"class\": \"2019\"}"
},
"display": {
"type": "html",
"data": "<p>This subject has received this Certificate of Accomplishment</p>"
},
"verification": {
"type": [
"MerkleProofVerification2017",
"Extension"
],
"publicKey": "ecdsa-koblitz-pubkey:1AwdUWQzJgfDDjeKtpPzMfYMHejFBrxZfo"
},
"proof": {
"type": "MerkleProof2019",
"creator": "did:example:abcdefghij0123456789",
"created": "2017-09-23T20:21:34Z",
"domain": "example.org",
"nonce": "2bbgh3dgjg2302d-d2b3gi423d42",
"proofValue":
"z76WGJzY2rXtSiZ8BDwU4VgcLqcMEm2dXdgVVS1QCZQUptZ5P8n5YCcnbuMUASYhVNihae7m8VeYvfViYf2KqTMVEH1B"
}
}
上面概述了几个选项。这个特定的示例使用 metadata 作为对象,display 为对象,holds 和 evidence 类似于 OB 的 credentialSubject 类型,并使用 MerkleProof2019 作为新的 signature / proof。这仅是示例,不一定是 Blockcerts V3 的“推荐” 路线。
2. Issuer Profile
作为 Open Badge 的扩展(并且可验证凭证协议和去中心化标识协议仍在标准化的同时),我们要求必须通过 https 来解析“issuer profile”配置文件,以获取诸如公钥、撤销列表甚至验证证书时收集的元数据(例如名称和图像)之类的信息。通过使用去中心化标识符(DID)的可验证凭证标准,我们不再需要依赖证书内的 URL 来获取此信息。
可验证凭证规范不要求使用 DID 来发行凭证,因此我们不建议将此项作为一个要求项,而是作为一个可选项。尽管我们可能需要进行某些更改以支持其它特定的方式,但我们可能还要继续支持基于 URL 的 issuer profile。
2.1
将发行者配置文件作为 DID
为了提供与 Blockcerts V2 相同的 UX,我们可能需要一些常规 DID 解析之外的东西。
以下是解析后的 DID 的示例:
{
"@context": "https://www.w3.org/2019/did/v1",
"id": "did:example:123456789abcdefghi",
"publicKeys": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "RsaVerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
}],
"service": [{
"id":"did:example:123456789abcdefghi#vcs",
"type": "VerifiableCredentialService",
"serviceEndpoint": "https://example.com/vc/"
}]
}
验证证书的完整性并证明某个颁发者确实已颁发证书的主要要求之一是查看 DID 的 publicKeys 属性中的 #key 字段。
可以通过引用 DID 和属性来链接签名密钥,例如:
did: example: 123456789abcdefghi#keys-1
但是,我们至少还需要保留一些其他内容来继承 DID 配置文件。
我们正在为 BlockcertsIssuer 提出一个服务端点,其中包含一些此类的元数据,以及一个用来处理证书撤销的 BlockcertsRevocation URL。
"service": [{
"id": "did:example:123456789abcdefghi#BlockcertsIssuer",
"type": "BlockcertsIssuerService",
"name": "University of Example,
"URL": "https://example.com",
"imageURL": "https://example.com/img.png",
"email": "test@example.com",
"serviceEndpoint": "https://example.com/introductionURL"
}]
解决颁发者 DID 的问题时,例如 did:example:123456789abcdefghi,我们可以查找与 BlockcertsIssuerService 相关的类型,以检查元数据并允许接收者将自己的 DID/公钥传给颁发者,就像当前对基于 URL 的 issuer profile 的做法一样。
BlockcertsRevocationService
我们可以在 BlockcertsIssuerService 中包括 BlockcertsRevocationService 作为一个字段,而不是一个独立的服务端点。我们可能需要研究服务端点之间的最佳实践。如果我们将其分成相关字段,则可能如下所示。
选项1:一次检查撤销单个 ID。
"service": [{
"id": "did:example:123456789abcdefghi#BlockcertsRevocation",
"type": "BlockcertsRevocationService",
"serviceEndpoint": "https://example.com/revocationEndpoint"
}]
如果颁发者想要撤销其已颁发证书的能力,则可以将 BlockcertsRevocationService 添加到其 DID 服务列表中。
这将使 Blockcerts 验证程序可以通过对 https://example.com/revocationEndpoint/{certId} 进行 GET 调用来检查证书的撤销状态。
选项2:检查 ID 的撤销列表。
创建此 BlockcertsRevocationService 的另一种方法是改为使其成为 BlockcertsRevocationListService,类似于我们今天执行 revocationList 的方式。
"service": [{
"id": "did:example:123456789abcdefghi#BlockcertsRevocationList",
"type": "BlockcertsRevocationListService",
"serviceEndpoint": "https://example.com/revocationListEndpoint"
}]
两种选项都有其优缺点。
选项1允许验证者仅获取并查看单个证书的撤销状态。验证者将无法查看其不拥有的证书的撤销状态。制作基于 UUID 的证书 ID 的标准做法应禁止验证者猜测其他证书 ID。
但是,选项1允许颁发者查看、记录、监视(等)特定证书。他们将能够看到正在尝试验证特定个人证书的 IP 地址、来源等信息,然后推断某些事情。
选项2提取了撤消事件的完整列表,这意味着它不会向发布者显示正在验证的颁发者,但会向验证者显示他们曾经进行过的每个撤消事件以及原因。在撤销列表很大的情况下,验证者可能必须等待所有撤销得到处理和检索才可以。
对于可验证凭证应使用哪种撤销/状态列表方法尚未达成很好的共识,因此尚无标准。理想情况下,对于所有可验证凭证撤销都有一个通用的 RevocationServiceEndpoint。同时,我们建议将其标记为特定于 Blockcerts 的撤销服务端点。
我们可能会同时支持这两种方法,而不是让 Blockcerts 标准选择这两种方法之一。允许发行人自己决定,这对他们的组织更有意义。
示例:
以下是发行人 DID 解析后的示例,采用选项2作为撤销机制:
{
"@context": "https://www.w3.org/2019/did/v1",
"id": "did:example:123456789abcdefghi",
"publicKeys": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}],
"service": [{
"id": "did:example:123456789abcdefghi#BlockcertsIssuer",
"type": "BlockcertsIssuerService",
"name": "University of Example,
"URL": "https://example.com",
"imageURL": "https://example.com/img.png",
"email": "test@example.com",
"serviceEndpoint": "https://example.com/introductionURL"
}, {
"id": "did:example:123456789abcdefghi#BlockcertsRevocationList",
"type": "BlockcertsRevocationListService",
"serviceEndpoint": "https://example.com/revocationListEndpoint"
}]
}
2.2
在 V3 中将发行者配置文件作为 URL
这是一个 Blockcerts V2 中 Issuer Profile 的示例:
{
"@context": [
"https://w3id.org/openbadges/v2",
"https://w3id.org/blockcerts/v2"
],
"type": "Profile",
"id": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json",
"name": "University of Learning",
"url": "https://www.issuer.org",
"introductionURL": "https://www.issuer.org/intro/",
"publicKey": [
{
"id": "ecdsa-koblitz-pubkey:msBCHdwaQ7N2ypBYupkp6uNxtr9Pg76imj",
"created": "2017-06-29T14:48:03.814936+00:00"
}
],
"revocationList": "https://www.blockcerts.org/samples/2.0/revocation-list-testnet.json",
"image": "data:image/png;base64,iVBORw0KGgo...",
"email": "contact@issuer.org"
}
与上面的颁发者 DID 示例相比,唯一需要更改的是如何处理 publicKey。
{
"@context": [
"https://w3id.org/openbadges/v2",
"https://w3id.org/blockcerts/v2"
],
"type": "Profile",
"id": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json",
"name": "University of Learning",
"url": "https://www.issuer.org",
"introductionURL": "https://www.issuer.org/intro/",
"publicKey": [{
"id": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}],
"revocationList": "https://www.blockcerts.org/samples/2.0/revocation-list-testnet.json",
"image": "data:image/png;base64,iVBORw0KGgo...",
"email": "contact@issuer.org"
}
这将使我们可以直接链接到用于签署可验证凭证的特定密钥,这是查找密钥的标准方法,而不是使用当前的 Blockcerts 模型来检查发行人声称的所有公钥与区块链交易密钥的对立关系。
不幸的是,由于在 Blockcert V2 中 publicKey 具有相同的属性名称,因此这个更改将使基于 URL 的 Issuer Profiles 处理起来有些棘手。我们要么使基于 URL 的 Issuer Profiles 无法同时处理 V2 和 V3 版本的 Blockcert,要么允许 V2 和 V3 两个版本的公钥。例如:
"publicKey": [
{
"id": "ecdsa-koblitz-pubkey:msBCHdwaQ7N2ypBYupkp6uNxtr9Pg76imj",
"created": "2017-06-29T14:48:03.814936+00:00"
},
{
"id": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "https://www.blockcerts.org/samples/2.0/issuer-testnet.json",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}
]
对于 V2,我们可能需要更新验证以忽略 id 为 did: 或 http: / https: URI 的情况。对于 V3,我们可能需要做相反的事情或忽略 id 不以#结尾的情况,就像在 VC / DID 模型中那样。
3. 结语
本期,我们介绍了 Blockerts V3 的一些示例及相关讨论,下期将会跟大家探讨一些 V2 和 V3 数据模型中的一些注意事项,欢迎大家关注。如有您有任何技术问题想与我们探讨,也欢迎大家通过 research@ont.io 反馈给我们哦。
▼点击阅读原文查看往期技术视点