关于DIDs的太多讨论
摘要
对AT Protocol(Bluesky)中使用的去中心化标识符(DIDs)进行技术深度解析,解释DID文档、验证方法和解析的工作原理。
<p><a href="https://lobste.rs/s/86lwsv/too_many_words_about_dids">评论</a></p>
查看缓存全文
缓存时间: 2026/07/14 18:19
# 关于DID的太多话
来源:https://steveklabnik.com/writing/too-many-words-about-dids/
发布日期:2026年7月14日
你的“Bluesky账号”不仅仅是*一个*Bluesky账号:它是一个可以在多种其他应用中使用的账号。这篇文章将从技术角度探讨这其中的部分含义,所以如果你不是软件开发者,这篇文章可能不适合你。但我要解释的是,你的账号如何独立于Bluesky——事实上,独立于任何特定应用——运作的技术机制。我们来谈谈身份:你到底是谁?任何系统的用户都需要某种方式描述自己是谁才能使用它。如果你想登录,你需要表明自己的身份;如果你想发帖,我们需要知道帖子的作者是谁。对于atproto(Bluesky及ATmosphere中其他应用所使用的协议),它们采用了“去中心化身份”标准,简称DID。W3C在2022年将DID标准化(https://www.w3.org/TR/did-1.0/)。正如其名,DID是一种标识符,可作为构建应用时身份的基础。其理念是这些标识符是去中心化的。然而,很多人对“去中心化”这个词有诸多看法,常常指责atproto并未真正去中心化。我们将详细探讨其工作原理,以便你理解并自行判断这种方法是否适合你。
## DID与DID文档
这是我的DID,以此为例:
`did:plc:3danwc67lo7obz2fmdg6jxcr`
它由三部分组成,以冒号分隔:方案(`did`)、方法(`plc`)和DID方法特定标识符(`3danwc67lo7obz2fmdg6jxcr`)。
要使用一个DID(例如`did:plc:3danwc67lo7obz2fmdg6jxcr`),你需要将其解析为一份DID文档(https://www.w3.org/TR/did-1.0/#dfn-did-documents):
> 描述DID主体的一组数据,包括诸如加密公钥等机制,DID主体或DID委托可用其进行身份验证并证明与该DID的关联。
该文档包含多种属性(https://www.w3.org/TR/did-1.0/#core-properties),用于描述身份。以下是我写作时的DID文档:
```json
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"id": "did:plc:3danwc67lo7obz2fmdg6jxcr",
"alsoKnownAs": ["at://steveklabnik.com"],
"verificationMethod": [
{
"id": "did:plc:3danwc67lo7obz2fmdg6jxcr#atproto",
"type": "Multikey",
"controller": "did:plc:3danwc67lo7obz2fmdg6jxcr",
"publicKeyMultibase": "zQ3shfNec2kPEb8cL77gSRMbCwbWE27p9nxKkcc4E82xtW8RJ"
}
],
"service": [
{
"id": "#atproto_pds",
"type": "AtprotoPersonalDataServer",
"serviceEndpoint": "https://morel.us-east.host.bsky.network"
}
]
}
```
这份文档提供了判断“我是谁”所需的一切信息——即,给定一条声称由我撰写的任意帖子,该文档描述了验证这一声明的方式。稍后我们会详细说明如何进行验证,但首先,你如何将那个DID解析为这份DID文档呢?很简单:每种方法都是一个标准,描述了具体如何解析。因此,当你看到`did:plc`时,意味着我们使用PLC标准,稍后会介绍;Bluesky支持的另一方法是`did:web`。此时你不会使用PLC标准,而是使用Web标准。这就是DID去中心化的含义:当你提供身份时,由你决定用哪种方法来验证该身份的真实性。没有中心化权威机构来决定哪些DID类型有效。当然,这并不意味着每个应用都支持所有DID方法,因为尽管这个规范*非常*通用,你仍然需要编写代码来实现特定的方法。我可以说“我是`did:foo:1243`”,但如果你的应用不支持`foo`方法,它就不会自动知道该怎么做。这是一个重要的注意事项。
## `did:web`
我们以`web`方法为例解释解析过程。虽然Bluesky支持它,但实际使用`did:web`的用户极少,不过它更简单,我认为先介绍它可以起到说明作用。我将以Liz Fong-Jones(https://bsky.app/profile/web.lizthegrey.com)的`did:web`账户为例。她该账户的身份是`did:web:lizthegrey.com`。那么如何将这个DID解析为DID文档呢?我们将方法特定标识符(这里是`lizthegrey.com`)放入以下URL模板:
`https://<domain>/.well-known/did.json`
然后你可以获取这个URL,解析出DID文档。写作时,它看起来是这样的:
```json
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"id": "did:web:lizthegrey.com",
"alsoKnownAs": [
"at://web.lizthegrey.com",
"did:plc:i4tfenpfog244rxry5uz4vtk"
],
"verificationMethod": [
{
"id": "did:web:lizthegrey.com#atproto",
"type": "Multikey",
"controller": "did:web:lizthegrey.com",
"publicKeyMultibase": "zQ3shnEqBNR5cuTePW8FyvnrRQaFf6Y7sCi5NBmDpteVXFjb6"
}
],
"service": [
{
"id": "#atproto_pds",
"type": "AtprotoPersonalDataServer",
"serviceEndpoint": "https://pds.lizthegrey.com"
}
]
}
```
这非常简单!那么为什么我们可能不想使用`did:web`呢?为什么还要费心使用其他系统?因为这种方法依赖于DNS系统。有人可能会认为,这终究还是某种形式的中心化。如果Liz的域名注册商吊销了她的域名,她也会失去对这个DID的控制。更泛化地说,如果Liz决定不再使用那个域名,她就会将该身份的控制权让给任何接手该域名的人。这种情况可能是非恶意的(比如域名过期后被他人购买),也可能是恶意的(比如她的注册商账户被黑导致域名被窃取)。此外,你需要在那个域名上运行一台永不停机的Web服务器;如果服务器宕机,你就无法获取文档。当这个DID文档发生变化时,客户端没有机制得知它已变更,这意味着应用可能使用过时的文档,或者更新文档与应用更新之间存在延迟,直到获取最新文档之前可能引发临时问题。
## `did:plc`
所有这些缺点促使Bluesky开发了自己的DID方法,试图解决上述及其他问题。这种方法称为`did:plc`(https://web.plc.directory/spec/v0.1/did-plc)。要解析`did:plc`,你将整个DID放入以下模板:
`https://plc.directory/<完整的DID>`
然后你可以获取该URL并获得DID文档。那么……区别在哪里?实际上,既没有区别也有区别。从字面上看,两者解析方式相同:都是获取一个URL。然而,细节很重要。与DID:Web相比,它已经有两个不同之处:
1. 你的DID不再绑定到特定域名。我可以让`steveklabnik.com`过期,然后迁移到`steve.klabnik.com`,而我的`did:plc`保持不变。
2. 虽然仍然需要运行Web服务器,但那是plc.directory的工作,而不是我自己的事。这在操作上要简单得多。
以上我呈现为优点,但也存在缺点。之前我需要信任DNS系统和域名注册商,现在我需要信任plc.directory。同样的注意事项也适用:我必须相信他们不会夺走我的ID,或者ID不会被窃取等。不过,也有一些重要的细节可以缓解这一问题,我们稍后会谈到。但对某些人来说,既不信任DNS也不信任plc.directory是可以接受的,还有其他的DID方法(例如使用区块链来解析名称)。Bluesky不支持使用这些DID方法,因此对于这个应用来说,它们并不相关,但知道它们的存在很重要。
为什么要这样做?最简单的说法是:设置`did:web`涉及很多“极客操作”。你需要注册域名,这会产生持续的费用;你需要知道如何设置Web服务器,并编写JSON文件放在服务器上;你需要保持服务器运行;你需要知道如何存储私钥并保证其安全。与“注册这个Web应用”相比,这几乎是不可能完成的任务。而Bluesky的目标是让这个平台对非极客用户可用。通过让plc.directory管理这一切,我们消除了所有这些步骤。
在起草本文期间,我还了解到`did:webvh`(https://identity.foundation/didwebvh/v1.0/),它扩展了`did:web`并试图纠正其一些缺点。我还没有阅读规范,但它已经达到1.0版,所以可能值得一看。我本想上周就发布这篇文章,不想再增加一节而推迟,但如果将来我重新写这篇文章,我可能会一并讨论它,所以在此提个醒。
## Bluesky是否拥有你的身份?
但这确实也意味着,在某种意义上,Bluesky仍然拥有你的身份。他们为你生成了一个密钥对,并且可以访问私钥。这对某些人是不可接受的。那么如何解决呢?实际上,`did:plc`有一些`did:web`所没有的额外功能。例如,`did:plc`允许你用ID注册额外的密钥对,并用它们轮换签名密钥。这样你就可以移除Bluesky生成的密钥,并插入你自己的密钥。虽然这是事实,但你的PDS需要使用你的密钥来签署你的帖子。因此,大多数人很可能将密钥存储在他们的PDS中,所以如果你使用Bluesky托管的PDS,你就已经将密钥上传到了他们的基础设施中,如果你试图让自己的身份远离Bluesky,这恐怕是不可接受的。当然,解决方案是运行你自己的PDS,然后轮换你的密钥。此时,你的密钥存在于你拥有的基础设施上,Bluesky再也无法干涉。我认为这种可能性是一个重要的设计特性,它允许有动机的用户真正拥有自己的身份。对这种做法的批评归结为“嗯,大多数用户不会这么做”,虽然这是事实,但我也认为这对大多数人来说是可以接受的,而且拥有选择权比强迫每个用户处理自己的密钥管理更重要。
## 总结
这篇文章的结尾有点突兀,但我只是想把这些内容“落笔”记录下来。希望你对身份以及它在atproto中的工作方式有了一些了解。
---
这是我在BlueSky上关于本文的帖子:
相似文章
DIDs 很酷,但我们并不需要它们
In a Moon 认为,尽管去中心化标识符(DID)在技术上是优雅的,但它们的用例并不需要它们——相反,选择了一个更简单的“主体”原语(命名空间:ID),该原语利用了已经嵌入在网页内容中的现有网络身份系统,例如 GitHub 用户名和电子邮件地址。
AT-URI 语法混乱
本文讨论了 AT URI 语法因将 DID 放在 authority 字段而导致与标准 URI/URL 规范不兼容的问题,并探讨了潜在的解决方案及其权衡。
ATProto 许可数据提案草案
Bluesky 已发布 AT 协议上许可数据的提案草案,同时还有用户列表、审核、OAuth 等其他提案,作为其持续开发工作的一部分。
Windows GDID 完整分析报告
对微软全局设备标识符(GDID)的详细逆向工程揭示,它是一个通过微软账户分配的64位Passport唯一ID,打破了其源自硬件序列号的传言。该报告记录了从wlidsvc到Connected Devices Platform再到Delivery Optimization的完整技术栈。
可验证的智能体基础设施:面向主权AI系统的基于证明的授权机制
本文提出了一种分布式信任框架(DTF),用于自主AI代理系统中的可验证、基于证明的授权,通过要求提供理由证明和共识执行来应对以身份为中心的权限所带来的风险。