去中心化标识符(DID)是一种用于可验证的"自主权"数字身份的新型标识符。DID 完全由 DID 控制者掌控,独立于任何集中式注册机构、身份提供者或证书颁发机构。DID 解析为 DID 文档——描述如何使用该特定 DID 的简单文档。
本文档规定了解析 DID 和解引用 DID URL 的算法与指南。此外,本文档描述了与 DID 解析过程相关的输入和输出元数据,并进一步描述了 DID 解析请求可能返回的数据结构。 本文档依赖于核心 DID 规范 Decentralized Identifiers (DIDs) v1.1, 该规范详细描述了底层 DID 架构。
欢迎对本文档提出意见。请直接在 GitHub 上提交问题, 或发送至 public-did-wg@w3.org (订阅, 存档)。
本规范的部分工作由美国国土安全部科学技术局根据合同 HSHQDC-17-C-00019 资助。本规范的内容不一定反映美国政府的立场或政策, 也不应推断为官方认可。
本规范的工作也得到了由 Christopher Allen、Shannon Appelcline、 Kiara Robles、Brian Weller、Betty Dhamers、Kaliya Young、Kim Hamilton Duffy、 Manu Sporny、Drummond Reed、Joe Andrieu 和 Heather Vescent 推动的 Rebooting the Web of Trust 社区的支持。
DID resolution 是为给定的 DID 获取 DID document 的过程。这是可以对任何 DID 执行的四种必需操作之一("读取";其他三种分别是"创建"、"更新"和"停用")。这些操作的具体细节取决于 DID method。 在 DID resolution 的基础上,DID URL dereferencing 是为给定的 DID URL 检索资源表示的过程。能够执行这些过程的软件和/或硬件称为 DID resolver。
本规范定义了 DID resolution 和 DID URL dereferencing 过程的通用要求、算法(包括其输入和结果)、架构选项以及各种注意事项。
请注意,虽然本规范定义了 DID 解析的一些基本功能,但与 DID 的 verifiable data registry 通信所需的实际步骤由适用的 DID method 规范定义。
通过使用标准的 resolve(did, resolutionOptions) 接口(如
DID 解析章节中所定义)调用 DID resolver,可以获取 DID document 及其附带的元数据
(例如 `contentType`、证明、版本信息),应用程序可以使用这些信息来验证用户的加密密钥、服务端点或状态。
例如,一个钱包应用可以使用 `versionTime` 参数解析 did:example:123?versionTime=2021-05-10T17:00:00Z
以检索该 DID 在过去某一时刻的状态,或者客户端可以解引用一个 DID URL,
如 did:example:123?service=files&relativeRef=/resume.pdf
(参见此处的详细示例),
以获取用户通过 DID 文档中声明的服务存储的简历。
此外,本规范的 DID URL 解引用算法展示了客户端如何通过
片段(例如 #key-1)从 DID document 中提取特定的验证方法
(参见此处的详细示例)。
在实践中,实现者通过
DID Resolution Test Suite 验证其解析器,
该测试套件测试规范性的 MUST 要求和错误条件(如无效 DID、已停用 DID、不支持的方法、
相对 URL 扩展等),以确保客户端应用程序能够可靠地依赖不同 DID 方法的正确解析行为。
conforming DID resolver(合规 DID 解析器)是指符合 中相关规范性声明的、以软件和/或硬件实现的任何算法。
conforming DID URL dereferencer(合规 DID URL 解引用器)是指符合 中相关规范性声明的、以软件和/或硬件实现的任何算法。
本规范有三类主要读者:合规 DID 方法的实现者;合规 DID 解析器的实现者;以及 希望使用 DID 解析器解析 DID 的系统和服务的实现者。目标读者包括但不限于 软件架构师、数据建模师、应用开发者、服务开发者、测试人员、运维人员和 用户体验(UX)专家。参与去中心化身份、可验证凭证和安全存储等广泛标准工作的 其他人员也可能有兴趣阅读本规范。
DID 解析规范旨在通过定义标准化接口来支持广泛的用例,以独立于任何特定 DID 的 DID 方法来解析 DID 和解引用 DID URL。这些用例包括:
DID URL 语法支持一种简单的参数格式 (参见 [[DID-CORE]] 中的 Query 章节)。向 DID URL 添加 DID 参数意味着该参数成为 resource 标识符的一部分。
did:example:123?versionTime=2021-05-10T17:00:00Z
did:example:123?service=files&relativeRef=/resume.pdf
对于存在的每个 DID 参数,其关联值必须(MUST)是根据 RFC3987 第 3.1 节序列化为 ASCII 的 标量值字符串。
某些 DID 参数完全独立于任何特定的 DID method,并且对所有 DIDs 的工作方式相同。其他 DID 参数并非所有 DID methods 都支持。在支持可选参数的情况下,它们预期在支持它们的 DID methods 之间统一运行。以下表格提供了在所有 DID methods 之间以相同方式运行的常见 DID 参数。对所有 DID 参数的支持是可选的(OPTIONAL)。
| 参数名称 | 描述 |
|---|---|
service
|
通过服务 ID 从 DID document 中标识一个 service。 |
serviceType
|
通过服务类型从 DID document 中标识一组一个或多个 services。 |
relativeRef
|
根据 RFC3986 第 4.2 节的相对 URI 引用,用于标识
service endpoint 处的 resource,该服务端点通过 service 参数从 DID
document 中选择。
|
versionId
|
标识要解析的 DID document 的特定版本(版本 ID 可以是顺序的、UUID 或方法特定的)。 |
versionTime
|
标识要解析的 DID document 的特定版本时间戳。即在指定 `versionTime` 之前对 DID 有效的最新版本的 DID document。如果存在,关联值必须(MUST)是一个 ASCII 字符串,且为有效的 XML 日期时间值,如 W3C XML Schema Definition Language
(XSD) 1.1 Part 2: Datatypes [[XMLSCHEMA11-2]] 第 3.3.7 节所定义。此日期时间值必须(MUST)标准化为 UTC 00:00:00 且不含亚秒小数精度。例如:2020-12-20T19:17:47Z。
|
hl
|
DID document 的资源哈希,用于添加完整性保护,如 [[?HASHLINK]] 中所指定。此参数为非规范性的。 |
实现者以及 DID method 规范作者可能使用此处未列出的其他 DID 参数。为了最大化互操作性,建议(RECOMMENDED)DID 参数使用 DID 文档属性扩展机制 [[?DID-EXTENSIONS-PROPERTIES]],以避免与具有不同语义的相同 DID 参数的其他用途发生冲突。
DID 参数可以(MAY)在存在明确用例的情况下使用,即该参数需要成为 URL 的一部分,以比单独使用 DID 更高的精度引用 resource。预期 DID 参数 在相同功能可以通过向 DID resolver 传递输入元数据来表达时,不使用 DID 参数。
DID resolution 和 DID URL dereferencing 函数可以通过向 DID resolver 传递不属于 DID URL 的 或 来影响其行为。这类似于 HTTP,其中某些参数可以包含在 HTTP URL 中,或者在解引用过程中作为 HTTP 头传递。重要的区别在于:作为 DID URL 一部分的 DID 参数应当用于指定正在标识什么 resource,而不属于 DID URL 的输入元数据应当用于控制如何解析或解引用该 resource。
DID resolution 函数通过使用适用 DID method 的"读取"操作将 DID 解析为 DID document,如 Method Operations 中所述。
所有合规的 DID resolvers 实现以下函数,其抽象形式如下:
resolve(did, resolutionOptions) →
« didResolutionMetadata, didDocument, didDocumentMetadata »
所有合规的 DID resolvers 必须(MUST)为至少一种 DID method 实现 DID resolution 函数,并且必须(MUST)能够以至少一种合规 representation 返回 DID document。
合规的 DID resolver 实现不以任何方式改变此函数的签名。DID resolver 实现可以(MAY)将
resolve 函数映射到方法特定的内部函数以执行实际的 DID resolution
过程。DID resolver 实现可以(MAY)在此处指定的 resolve 函数之外实现和暴露具有不同签名的额外函数。
resolve 函数的输入变量如下:
did 本身之外的 resolve 函数的输入选项。此结构在 中进一步定义。此输入是必需的(REQUIRED),但结构可以(MAY)为空。
此函数返回多个值,不对这些值如何一起返回施加限制。resolve 的返回值是
didResolutionMetadata、didDocument 和
didDocumentMetadata。这些值描述如下:
error 属性。参见 章节。
id 的值必须(MUST)与被解析的 DID 字符串等价。如果解析不成功,此值必须(MUST)为空。
didDocument
属性中 DID document 的元数据。如果解析不成功,此输出必须(MUST)是一个空的 元数据结构。此结构在 中进一步定义。
这是一个元数据结构,包含 DID Resolution 过程的输入选项。
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册。本规范定义了以下常见输入选项:
didDocument 的 representation(如果支持且可用该 representation)。此属性是可选的(OPTIONAL)。
这是一个元数据结构,包含关于 DID Resolution 过程的元数据。
此元数据通常在每次调用 DID Resolution 函数时发生变化,因为它表示解析过程本身的数据。
此元数据的来源是 DID resolver。
DID 解析元数据的示例包括:
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册。本规范定义了以下常见元数据属性:
didDocument 的媒体类型。此属性是可选的(OPTIONAL)。如果存在,此属性的值必须(MUST)是一个 ASCII 字符串,即合规 representations 的媒体类型。在这种情况下,resolve 函数的调用者必须(MUST)在确定如何解析和处理 didDocument 时使用此值。
某些 DID resolvers 和 DID URL dereferencers 在执行 DID Resolution 或 DID URL Dereferencing 函数时使用证明。详见 。
DID resolution 元数据可以(MAY)包含 proof 属性。如果存在,其值必须(MUST)是一个 集合,其中每个项目是一个表示证明的 映射。此属性的使用和证明类型与 DID method 无关。
这是一个元数据结构,包含关于 DID Resolution 过程的元数据。
此元数据通常不会在 DID Resolution 函数的调用之间发生变化,除非 DID document 发生更改,因为它表示关于 DID document 的数据。
此元数据的来源是 DID controller 和/或 DID method。 由 DID 控制者证明的 DID 文档元数据没有内在的准确性保证。建议客户端在依赖 DID 文档元数据来指导业务逻辑时保持谨慎。
DID 文档元数据的示例包括:
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Document Properties Extensions [[?DID-EXTENSIONS-PROPERTIES]] 中注册。本规范定义了以下常见元数据属性。
created 属性,以指示 Create 操作的时间戳。该属性的值必须(MUST)是格式化为 XML Datetime 的 字符串,标准化为 UTC 00:00:00 且不含亚秒小数精度。例如:2020-12-20T19:17:47Z。
updated 属性,以指示已解析文档版本的最后一次 Update 操作的时间戳。该属性的值必须(MUST)遵循与 created 属性相同的格式规则。如果从未对 DID document 执行过 Update 操作,则省略 updated 属性。如果 updated 属性存在,当两个时间戳之间的差异小于一秒时,其值可以与 created 属性的值相同。
true。如果 DID 未被停用,此属性是可选的(OPTIONAL),但如果包含,必须(MUST)具有布尔值 false。
nextUpdate 属性。它指示下一次 Update 操作的时间戳。该属性的值必须(MUST)遵循与 created 属性相同的格式规则。
versionId 属性,以指示已解析文档版本的最后一次 Update 操作的版本。该属性的值必须(MUST)是一个 ASCII 字符串。
nextVersionId 属性。它指示下一次 Update 操作的版本。该属性的值必须(MUST)是一个 ASCII 字符串。
DID method 可以定义逻辑等价的不同 DID 形式。例如,DID 在注册到 verifiable data registry 之前采用一种形式,注册后采用另一种形式。在这种情况下,DID method 规范可能需要将一个或多个逻辑等价于已解析 DID 的 DIDs 表示为 DID document 的属性。这就是 equivalentId 属性的用途。
DID document 元数据可以(MAY)包含 equivalentId 属性。如果存在,其值必须(MUST)是一个 集合,其中每个项目是符合 章节规则的 字符串。该关系声明每个 equivalentId 值在逻辑上等价于 id 属性值,因此指向相同的 DID subject。每个 equivalentId DID 值必须(MUST)由与 id 属性值相同的 DID method 产生,并且是其形式之一。(例如,did:example:abc == did:example:ABC)
合规的 DID method 规范必须(MUST)保证每个 equivalentId 值在逻辑上等价于 id 属性值。
请求方应保留 id 和 equivalentId 属性中的值,以确保与其中任何值的后续交互都能作为逻辑等价正确处理(例如,在数据库中保留所有变体,以便与任何一个的交互都映射到相同的底层账户)。
equivalentId 是比 alsoKnownAs 更强的等价形式,因为这种等价性必须(MUST)由管辖的 DID method 保证。使用 equivalentId 意味着同一个 DID document 描述了 equivalentId DID 和 id 属性 DID。
如果请求方未保留 id 和 equivalentId 属性中的值,并确保与其中任何值的后续交互都能作为逻辑等价正确处理,则可能出现负面或意外问题。强烈建议实现者遵守与此元数据属性相关的指令。
canonicalId 属性与 equivalentId 属性相同,不同之处在于:a)它与单个值而非集合关联,b)该 DID 被定义为在包含它的 DID document 范围内 DID subject 的规范 ID。
DID document 元数据可以(MAY)包含 canonicalId 属性。如果存在,其值必须(MUST)是符合 章节规则的 字符串。该关系声明 canonicalId 值在逻辑上等价于 id 属性值,并且 canonicalId 值由 DID method 定义为在包含它的 DID document 范围内 DID
subject 的规范 ID。canonicalId 值必须(MUST)由与 id 属性值相同的 DID method 产生,并且是其形式之一。(例如,did:example:abc == did:example:ABC)。
合规的 DID method 规范必须(MUST)保证 canonicalId 值在逻辑上等价于 id 属性值。
请求方应使用 canonicalId 值作为 DID subject 的主要 ID 值,并将所有其他等价值视为次要别名(例如,更新系统中对应的主要引用以反映新的规范 ID 指令)。
canonicalId 与 equivalentId 是相同的等价声明,只是它被约束为单个值,该值被定义为在 DID document 范围内 DID subject 的规范值。与 equivalentId 一样,使用 canonicalId 意味着同一个 DID document 描述了 canonicalId DID 和 id 属性 DID。
如果解析方未使用 canonicalId 值作为 DID 主体的主要 ID 值,并将所有其他等价值视为次要别名,则可能出现与用户体验相关的负面或意外问题。强烈建议实现者遵守与此元数据属性相关的指令。
许多 DID methods 在执行 方法操作时使用证明。详见 。
DID document 元数据可以(MAY)包含 proof 属性。如果存在,其值必须(MUST)是一个 集合,其中每个项目是一个表示证明的 映射。此属性的使用和证明类型是 DID method 特定的。
以下 DID resolution 算法必须(MUST)由合规的 DID resolver 实现。
null«[ ]»null«[ ]»null«[ ]»«[ ... ]»null«[ "deactivated" → true, ... ]»true 的 expandRelativeUrls 选项:
id 属性值是
相对 DID URL,或者
verification relationship 是
相对 DID URL:
«[ ... ]»«[ "contentType" → 输出 DID 文档媒体类型, ... ]»DID URL dereferencing 函数将 DID URL 解引用为一个 resource,其内容取决于 DID URL 的各组成部分,包括 DID method、方法特定标识符、路径、查询和片段。此过程依赖于 DID URL 中包含的 DID 的 DID resolution。DID URL dereferencing 可能涉及多个步骤(例如,当正在解引用的 DID URL 包含片段时),该函数被定义为在所有步骤完成后返回最终资源。下图描述了上述关系。
图的左上部分包含一个黑色轮廓的矩形,标记为"DID"。
图的左下部分包含一个黑色轮廓的矩形,标记为"DID URL"。此矩形包含四个较小的黑色轮廓矩形,水平排列相邻。这些较小的矩形依次标记为"DID"、"path"、"query"和"fragment"。
图的右上部分包含一个黑色轮廓的矩形,标记为"DID document"。此矩形包含三个较小的黑色轮廓矩形。这些较小的矩形标记为"id"、"(property X)"和"(property Y)",并被多组省略号包围。一条标记为"DID document - relative fragment dereference"的黑色弯曲箭头从标记为"(property X)"的矩形延伸,指向标记为"(property Y)"的矩形。
图的右下部分包含一个黑色轮廓的椭圆形,标记为"Resource"。
一条标记为"resolves to a DID document"的黑色箭头从图左上部分标记为"DID"的矩形延伸,指向图右上部分标记为"DID document"的矩形。
一条标记为"refers to"的黑色箭头从图右上部分标记为"DID document"的矩形延伸,指向图右下部分标记为"Resource"的椭圆形。
一条标记为"contains"的黑色箭头从图左下部分标记为"DID URL"的矩形中标记为"DID"的小矩形延伸,指向图左上部分标记为"DID"的矩形。
一条标记为"dereferences to a DID document"的黑色箭头从图左下部分标记为"DID URL"的矩形延伸,指向图右上部分标记为"DID document"的矩形。
一条标记为"dereferences to a resource"的黑色箭头从图左下部分标记为"DID URL"的矩形延伸,指向图右下部分标记为"Resource"的椭圆形。
所有合规的 DID URL dereferencers 实现以下函数,其抽象形式如下:
dereference(didUrl, dereferenceOptions) →
« dereferencingMetadata, contentStream, contentMetadata »
dereference 函数的输入变量如下:
虽然将任何 didUrl 传递给 DID URL 解引用器都是有效的,但实现者应参考 以进一步了解 DID URL 预期如何被解引用的常见模式。
didUrl 本身之外的 dereference 函数的输入选项。此结构在 中进一步定义。此输入是必需的(REQUIRED),但结构可以(MAY)为空。
此函数返回多个值,不对这些值如何一起返回施加限制。dereference 的返回值是
dereferencingMetadata、contentStream 和
contentMetadata。这些值描述如下:
error 属性。参见 章节。
dereferencing 函数且成功,此值必须(MUST)包含对应于 DID URL 的 resource。contentStream 可以(MAY)是可以以一种合规 representations 序列化的 resource(如 DID
document)、verification
method、service,或通过解析过程可以获取的任何其他可通过媒体类型标识的资源格式。如果解引用不成功,此值必须(MUST)为空。
contentStream 的元数据。如果 contentStream 是 DID document,此值必须(MUST)是 DID Resolution 中描述的 didDocumentMetadata 结构。如果解引用不成功,此输出必须(MUST)是一个空的 元数据结构。此结构在 中进一步定义。
合规的 DID URL dereferencing 实现不以任何方式改变这些函数的签名。DID URL dereferencing 实现可以将 dereference 函数映射到方法特定的内部函数以执行实际的 DID URL
dereferencing 过程。DID URL dereferencing 实现可以在此处指定的 dereference 函数之外实现和暴露具有不同签名的额外函数。
这是一个元数据结构,包含 DID URL Dereferencing 过程的输入选项。
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册。本规范定义了以下常见输入选项:
contentStream 媒体类型。媒体类型必须(MUST)表示为 ASCII 字符串。DID URL dereferencer 实现应当(SHOULD)使用此值来确定返回值中包含的 representation 的 contentType(如果支持且可用该 representation)。
这是一个元数据结构,包含关于 DID URL Dereferencing 过程的元数据。
此元数据通常在每次调用 DID URL Dereferencing 函数时发生变化,因为它表示解引用过程本身的数据。
此元数据的来源是 DID URL dereferencer。
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册。本规范定义了以下常见元数据属性:
contentStream 的媒体类型应当(SHOULD)使用此属性表示。媒体类型值必须(MUST)表示为 ASCII 字符串。
某些 DID resolvers 和 DID URL dereferencers 在执行 DID Resolution 或 DID URL Dereferencing 函数时使用证明。详见 。
DID URL dereferencing 元数据可以(MAY)包含 proof 属性。如果存在,其值必须(MUST)是一个 集合,其中每个项目是一个表示证明的 映射。此属性的使用和证明类型与 DID method 无关。
这是一个元数据结构,包含关于 DID URL Dereferencing 过程的元数据。
此元数据通常不会在 DID URL Dereferencing 函数的调用之间发生变化,除非内容发生更改,因为它表示关于内容的数据。
此元数据的来源是 DID controller 和/或 DID method。
此结构中可能的属性及其可能的值应当(SHOULD)在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册。本规范不定义常见属性。
以下 DID URL dereferencing 算法必须(MUST)由合规的 DID resolver 实现。根据 [[RFC3986]],它由以下三个步骤组成:解析 DID;解引用资源;以及解引用片段(仅当输入 DID URL 包含 DID fragment 时):
null«[ ]»null«[ ]»did:example:1234DID URL dereferencer 必须(MUST)按以下方式返回已解析的 DID document 和已解析的 :
«[ ... ]»已解析的 DID 文档«[ 已解析的 DID 文档元数据 ]»hl:
did:example:1234?hl=zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e
TODO: 指定处理 `hl` DID 参数的算法。
service 和/或
DID 参数 serviceType,以及可选的
DID 参数 relativeRef:
did:example:1234?service=files&relativeRef=%2Fmyresume%2Fdoc%3Fversion%3Dlatest
service:
如果 service 的 id
属性与 service DID 参数的值匹配,则选择该服务。如果 id
属性或 service DID 参数或两者都包含相对引用,则必须(MUST)根据 RFC3986 第 5 节:引用解析和 [[[DID-CORE]]] 中 相对 DID URL 章节中指定的规则解析并使用对应的绝对 URI 来确定匹配。serviceType:
如果 service 的 type
属性与 serviceType DID 参数的值匹配,则选择该服务。relativeRef:
serviceEndpoint 属性值是一个 映射,跳过此所选 service。serviceEndpoint 属性值是一个 字符串,将此值添加到所选 service endpoint URL 列表中。serviceEndpoint 属性值是一个 集合,将其中所有 字符串项添加到所选 service endpoint URL 列表中。relativeRef 的值。解析 service endpoint——特别是当它是 DID 时——可能导致 resolution cycle(解析循环),即一组导致无限循环的步骤。例如,service endpoint 可能通过一系列解析间接指回先前已解引用的标识符。递归解析 service endpoint 的 DID resolver 应检测并处理此类循环,以防止无限循环或解析失败。进一步指导请参见 解析循环章节。
«[ ... ]»包含所选服务的已解析 DID 文档«[ 已解析的 DID 文档元数据 ]»«[ ... ]»« 所选服务端点 URL »«[ "contentType" → "text/uri-list", ... ]»null«[ ]»did:example:1234/custom/path?customquery
null«[ ]»如果输入 DID URL 包含 DID fragment,则片段的解引用取决于资源的媒体类型([[RFC2046]]),即 的结果。
verificationRelationship 选项:
verificationRelationship 选项的值。
did:example:1234?service=files&relativeRef=%2Fmyresume%2Fdoc%3Fversion%3Dlatest#intro
fragment 组件,引发错误。application/did 的 DID 文档表示,则片段按与 JSON-LD 1.1: application/ld+json 媒体类型 [JSON-LD11] 关联的规则处理。
此 DID fragment 的使用与 [[RFC3986]] 中片段标识符的定义一致。它标识的是次要资源,是主要资源(DID document)的子集。
DID fragment 的此行为类似于 HTTP URL 中片段的处理方式,即当解引用它返回带有 Location 头的 HTTP 3xx(重定向)响应时(参见 [[RFC7231]] 第 7.1.2 节)。
给定以下输入 DID URL:
did:example:123456789abcdefghi#keys-1
... 以及以下已解析的 DID document:
{
"@context":[
"https://www.w3.org/ns/did/v1.1",
"https://didcomm.org/messaging/contexts/v2",
"https://identity.foundation/linked-vp/contexts/v1"
],
"id": "did:example:123456789abcdefghi",
"verificationMethod": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Multikey",
"controller": "did:example:123456789abcdefghi",
"publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
}],
"service": [{
"id": "did:example:123456789abcdefghi#messages",
"type": "DIDCommMessaging",
"serviceEndpoint": "https://example.com/messages/8377464"
}, {
"id": "did:example:123456789abcdefghi#linkedvp",
"type": "LinkedVerifiablePresentation",
"serviceEndpoint": "https://example.com/verifiable-presentation.jsonld"
}]
}
{
"@context": "https://www.w3.org/ns/did/v1.1",
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Multikey",
"controller": "did:example:123456789abcdefghi",
"publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
}
给定以下输入 DID URL:
did:example:123456789abcdefghi?service=messages&relativeRef=%2Fsome%2Fpath%3Fquery#frag
... 以及上一节中相同的已解析的 DID document。
... 则 算法的结果为以下所选 service endpoint URL:
https://example.com/messages/8377464/some/path?query#frag
在 DID Resolution、DID URL dereferencing 及其他 DID 相关过程中通常涉及输入和输出元数据。用于传达此元数据的结构必须(MUST)是一个属性 映射。每个属性名必须(MUST)是一个 字符串。每个属性值必须(MUST)是 字符串、数字、映射、列表、集合、布尔值或 null。任何复杂数据结构(如映射或列表)中的值也必须(MUST)是这些数据类型之一。在 DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] 中注册的所有元数据属性定义必须(MUST)定义值类型,包括对该值的任何其他格式或限制(例如,格式化为日期的字符串)。建议(RECOMMENDED)属性定义使用字符串作为值。整个元数据结构必须(MUST)可根据 [[INFRA]] 规范中的 JSON 序列化规则进行序列化。实现可以(MAY)将元数据结构序列化为其他数据格式。
所有使用元数据结构作为输入或输出的函数实现都能够以确定性方式完全表示此处描述的所有数据类型。由于使用元数据结构的输入和输出是根据数据类型而非其序列化来定义的,因此 representation 的方法是函数实现内部的,超出本规范的范围。
以下示例展示了一个可能用作 DID 解析输入元数据的 JSON 编码元数据结构。
{
"accept": "application/did"
}
此示例对应于以下格式的元数据结构:
«[ "accept" → "application/did" ]»
下一个示例展示了当 DID 未找到时可能用作 DID 解析元数据的 JSON 编码元数据结构。
{
"error": "notFound"
}
此示例对应于以下格式的元数据结构:
«[ "error" → "notFound" ]»
下一个示例展示了可能用作 DID 文档元数据的 JSON 编码元数据结构,用于描述与 DID document 相关联的时间戳。
{
"created": "2019-03-23T06:35:22Z",
"updated": "2023-08-10T13:40:06Z"
}
此示例对应于以下格式的元数据结构:
«[ "created" → "2019-03-23T06:35:22Z", "updated" → "2023-08-10T13:40:06Z" ]»
DID resolution 算法涉及根据其 DID method 对 DID 执行 Read 操作(参见 )。
每个 DID 方法都定义了此方法操作,即 DID resolver 如何从 DID 获取 DID 文档。底层数据格式、协议、技术基础设施和流程在不同 DID methods 之间可能差异很大。
DID 方法注意事项的示例包括以下内容:
基于上述注意事项以及 DID method's "读取"操作的性质,DID resolver 与 verifiable data registry 之间的交互可被视为 verifiable read 或 unverifiable read:
verifiable read 在适用 DID method 下可能的范围内最大化对"读取"操作结果的完整性和正确性的信心。这可以通过多种方式实现,例如以下方式:
unverifiable read 没有这样的保证,因此不太理想,例如:
verifiable read 是否可能不仅取决于 DID method 本身,还取决于 DID resolver 实现该 DID method 的方式。DID methods 可以(MAY)允许多种实现其"读取"操作的方式,并应当(SHOULD)提供关于至少一种实现 verifiable read 的方式的指导。
与 verifiable read 相关的保证始终受到 DID method's 底层 verifiable data registry 的架构、协议、加密元素和其他方面的限制。被认为最强的 verifiable read 实现形式是那些不需要与任何远程网络交互的形式(例如,参见 [[DID-KEY]]),以及那些最小化对特定网络基础设施依赖的形式,将"信任根"减少到经验证的熵和密码学(例如,参见 [[KERI]])。
为了启用 verifiable reads,许多 DID 方法使用数字签名、状态证明、Merkle 树包含证明、加密事件日志或其他类型的证明。如果 DID method 使用此类证明,它必须(MUST)在其 DID 方法规范中指定如何使用它们来验证"读取"操作结果的正确性。
DID method 也可以(MAY)将此类证明包含在 DID document 本身中,或包含在 DID 文档元数据的 proof 属性中。这可能使 client 能够独立验证 DID Resolution 过程的结果,即使它不信任 DID resolver。
请注意,来自 DID method 的证明是 DID method 特定的,必须在适用 DID method 的技术框架内理解。DID document 或 DID 文档元数据上的简单签名并不一定证明对 DID 的控制权,也不保证 DID document 对于该 DID 是正确的。这些证明有助于验证 DID Resolution 过程结果的完整性和真实性(就 DID method 本身而言)。然而,它们不保证 client 与 DID resolver 之间的 binding 是安全的。另请参见 。
DID resolution 和 DID URL dereferencing 的算法定义为抽象函数(参见 和 )。
这些算法由 DID resolvers 和 DID URL dereferencers 实现,由 client 通过 binding 调用。绑定定义了如何使用具体的编程或通信接口访问抽象函数。
绑定的示例包括以下内容:
基于上述注意事项以及绑定的性质,client 与 DID resolver 或 DID URL dereferencer 之间的交互可被视为 local binding 或 remote binding:
在可能的情况下,首选 local bindings,因为它们最大限度地减少对第三方和中间方的依赖,降低安全风险,并最大化对 DID resolution 和 DID URL dereferencing 函数结果的完整性和正确性的信心。
在某些情况下,可能无法使用 local binding;例如,在受限的物联网(IoT)环境中,或当 DID method 需要复杂的基础设施时,或当需要支持多种不同的 DID methods 时。
如果 client 使用 remote binding,适用以下注意事项:
DID resolver 也可以(MAY)在 DID 解析元数据的 proof 属性中包含证明。此包含可能使 client 能够独立验证 DID Resolution 过程的结果,只要它信任 DID resolver。
请注意,来自 DID resolver 的证明与 DID method 无关,可以由 DID resolver 跨所有 DID 方法普遍应用。这些证明有助于验证 DID Resolution 过程结果的完整性和真实性(就 DID resolver 本身而言)。然而,它们不保证适用 DID method 的"读取"操作的结果本身是正确的。另请参见 。
DID resolver 必须(MUST)支持至少一种 DID method 的 DID resolution 算法,并且可以(MAY)支持多种 DID methods:
在这种情况下, 中关于 verifiable read 和 unverifiable read 实现的上述注意事项分别适用于每个支持的 DID method。
DID resolver 可以(MAY)调用另一个 DID resolver,后者作为代理执行 中定义的 DID resolution 算法。
第一个 DID resolver 随后充当 client 的角色,并为调用第二个 DID resolver 选择合适的 binding。例如,DID resolver 可以通过 local binding(如命令行工具)调用,后者又通过 remote binding(如 HTTP(S) 绑定)调用另一个 DID resolver。
在使用代理解析时,"下游"解析器应当(SHOULD)以透明的方式保留来自"上游"解析器的所有 DID 解析元数据和 DID 文档元数据,包括可能存在的任何证明。在此过程中,"下游"解析器可以(MAY)添加自己的 DID 解析元数据,包括关于代理解析过程本身的任何元数据。
这类似于 DNS 架构中"存根解析器"调用"递归解析器",尽管这些概念并非完全可比(DNS 解析使用单一的具体协议,而 DID 解析是由不同 DID methods 和不同 bindings 实现的抽象函数)。
DID URL 解引用算法的不同部分可能由解析器架构的不同组件执行。
具体来说,当解引用带有 DID fragment 的 DID URL 时,解引用资源由 DID resolver 完成,而 解引用片段由 client 完成。
给定 DID URL did:xyz:1234#keys-1,可以通过 local binding 调用 DID resolver 来执行 解引用资源(即 DID document),client 可以通过 解引用片段(即 DID document 的一部分)来完成 DID URL dereferencing 算法。
给定 DID URL did:xyz:1234?service=agent&relativeRef=%2Fsome%2Fpath%3Fquery#frag,可以调用 DID resolver 来执行 解引用资源(即 service endpoint URL),client 可以通过 解引用片段(即带片段的 service endpoint URL)来完成 DID URL dereferencing 算法。
给定 DID URL did:xyz:1234#keys-1,可以通过 local binding 调用 DID resolver,后者通过 remote binding 调用另一个 DID resolver 来执行 解引用资源(即 DID document),client 可以通过 解引用片段(即 DID document 的一部分)来完成 DID URL dereferencing 算法。
本节定义了一个表示 中所述算法结果的 JSON 数据结构。DID resolution result 包含 DID document 以及 DID 解析元数据和 DID 文档元数据。
此数据结构的媒体类型定义为 `application/did-resolution`。
{
"didDocument": {
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:example:123456789abcdefghi",
"authentication": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}],
"service": [{
"id":"did:example:123456789abcdefghi#vcs",
"type": "VerifiableCredentialService",
"serviceEndpoint": "https://example.com/vc/"
}]
},
"didResolutionMetadata": {
"contentType": "application/did",
"retrieved": "2024-06-01T19:73:24Z",
},
"didDocumentMetadata": {
"created": "2019-03-23T06:35:22Z",
"updated": "2023-08-10T13:40:06Z",
"method": {
"nymResponse": {
"result": {
"data": "{\"dest\":\"WRfXPg8dantKVubE3HX8pw\",\"identifier\":\"V4SGRU86Z58d6TV7PBUe6f\",\"role\":\"0\",\"seqNo\":11,\"txnTime\":1524055264,\"verkey\":\"H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV\"}",
"type": "105",
"txnTime": 1.524055264E9,
"seqNo": 11.0,
"reqId": 1.52725687080231475E18,
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"dest": "WRfXPg8dantKVubE3HX8pw"
},
"op": "REPLY"
},
"attrResponse": {
"result": {
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"seqNo": 12.0,
"raw": "endpoint",
"dest": "WRfXPg8dantKVubE3HX8pw",
"data": "{\"endpoint\":{\"xdi\":\"http://127.0.0.1:8080/xdi\"}}",
"txnTime": 1.524055265E9,
"type": "104",
"reqId": 1.52725687092557056E18
},
"op": "REPLY"
}
}
}
}
本节定义了一个表示 中所述算法结果的 JSON 数据结构。DID URL dereferencing result 包含内容以及 DID URL 解引用元数据和 DID URL 内容元数据。
此数据结构的媒体类型定义为 `application/did-url-dereferencing`。
{
"content": {
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:example:123456789abcdefghi",
"authentication": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}],
"service": [{
"id":"did:example:123456789abcdefghi#vcs",
"type": "VerifiableCredentialService",
"serviceEndpoint": "https://example.com/vc/"
}]
},
"didUrlDereferencingMetadata": {
"contentType": "application/did",
"retrieved": "2024-06-01T19:73:24Z",
},
"contentMetadata": {
"created": "2019-03-23T06:35:22Z",
"updated": "2023-08-10T13:40:06Z",
"method": {
"nymResponse": {
"result": {
"data": "{\"dest\":\"WRfXPg8dantKVubE3HX8pw\",\"identifier\":\"V4SGRU86Z58d6TV7PBUe6f\",\"role\":\"0\",\"seqNo\":11,\"txnTime\":1524055264,\"verkey\":\"H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV\"}",
"type": "105",
"txnTime": 1.524055264E9,
"seqNo": 11.0,
"reqId": 1.52725687080231475E18,
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"dest": "WRfXPg8dantKVubE3HX8pw"
},
"op": "REPLY"
},
"attrResponse": {
"result": {
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"seqNo": 12.0,
"raw": "endpoint",
"dest": "WRfXPg8dantKVubE3HX8pw",
"data": "{\"endpoint\":{\"xdi\":\"http://127.0.0.1:8080/xdi\"}}",
"txnTime": 1.524055265E9,
"type": "104",
"reqId": 1.52725687092557056E18
},
"op": "REPLY"
}
}
}
}
本规范中描述的算法会抛出特定类型的错误。实现者可能会发现将这些错误传达给其他库或软件系统很有用。本节为错误提供了特定的 URL 和描述,以便实现本规范所述技术的生态系统在发生错误时可以更有效地互操作。此外,本规范使用了 [[CID]] 规范 第 3.5 节处理错误中定义的一些错误。
实现者应当(SHOULD)使用 [[RFC9457]] 来编码错误数据结构。如果使用 [[RFC9457]]:
accept 输入元数据属性请求的 representation 不被 DID method 和/或 DID resolver 实现支持。参见 章节。
本节定义了一个 DID resolver binding,通过 HTTP(S) 端点暴露 DID resolution 和/或 DID URL dereferencing 函数(包括所有解析/解引用选项和元数据)。参见 。
HTTP(S) 绑定需要一个已知的 HTTP(S) URL,可以在该 URL 处调用 DID resolver。此 URL 称为 DID resolver HTTP(S) 端点。
此绑定通常被视为 remote binding,但如果 HTTP(S) 端点在本地环境中运行(如 localhost),也可以是 local binding。
使用此绑定,可以按以下方式执行 DID resolution 函数(参见 )和/或 DID URL dereferencing 函数(参见 ):
https://resolver.example/1.0/identifiers/
https://resolver.example/1.0/identifiers/did:example:1234
Accept HTTP 请求头设置为 `application/did-resolution` 以请求完整的 ,或者Accept HTTP 请求头设置为 accept 解析选项的值以仅请求结果中的 didDocument 值。https://resolver.example/1.0/identifiers/did:example:1234?service=files&relativeRef=/resume.pdf
Accept HTTP 请求头设置为 `application/did-url-dereferencing` 以请求完整的 ,或者Accept HTTP 请求头设置为 accept 解引用选项的值以仅请求结果中的 contentStream 值。GET 请求。这将在远程 DID resolver 上调用 DID resolution 或 DID URL dereferencing 函数。
GET https://resolver.example/1.0/identifiers/did%3Aexample%3A1234?option1=value1&option2=value2 HTTP/1.1 Accept: application/did-resolution
GET https://resolver.example/1.0/identifiers/did%3Aexample%3A1234%3Fservice%3Dfiles%26relativeRef%3D%2Fresume.pdf?option1=value1&option2=value2 HTTP/1.1 Accept: application/did-url-dereferencing
POST 请求。这将在远程 DID resolver 上调用 DID resolution 或 DID URL dereferencing 函数。
POST https://resolver.example/1.0/identifiers/did:example:1234 HTTP/1.1
Accept: application/did-resolution
{
"option1": "value1",
"option2": "value2"
}
POST https://resolver.example/1.0/identifiers/did:example:1234?service=files&relativeRef=/resume.pdf HTTP/1.1
Accept: application/did-url-dereferencing
{
"option1": "value1",
"option2": "value2"
}
| 错误 | HTTP 状态码 |
|---|---|
INVALID_DID
|
400
|
INVALID_DID_URL
|
400
|
INVALID_OPTIONS
|
400
|
NOT_FOUND
|
404
|
REPRESENTATION_NOT_SUPPORTED
|
406
|
INVALID_DID_DOCUMENT
|
500
|
METHOD_NOT_SUPPORTED
|
501
|
INVALID_PUBLIC_KEY
|
500
|
INVALID_PUBLIC_KEY_LENGTH
|
500
|
INVALID_PUBLIC_KEY_TYPE
|
500
|
UNSUPPORTED_PUBLIC_KEY_TYPE
|
501
|
INTERNAL_ERROR
|
500
|
| (any other value) |
500
|
true 的 deactivated 元数据属性:
410。Content-Type HTTP 响应头的值为 `application/did-resolution`:
200。Content-Type HTTP 响应头。其值必须(MUST)为 didResolutionMetadata 中 contentType 元数据属性的值(参见 )。Content-Type HTTP 响应头的表示形式。Content-Type HTTP 响应头的值为 `application/did-url-dereferencing`:
text/uri-list 的 contentType 元数据属性:
303。Location 头。此头的值必须(MUST)为所选 service endpoint URL。200。Content-Type HTTP 响应头。其值必须(MUST)为 dereferencingMetadata 中 contentType 元数据属性的值(参见 )。Content-Type HTTP 响应头的表示形式。参见此处获取对应 HTTP(S) 绑定的 OpenAPI 定义。
给定以下 DID resolver HTTP(S) 端点:
https://resolver.example/1.0/identifiers/
以及给定以下输入 DID:
did:example:123
则请求 HTTP(S) URL 为:
https://resolver.example/1.0/identifiers/did:example:123
可以通过 HTTP(S) 绑定按以下方式调用 resolve() 函数:
GET https://resolver.example/1.0/identifiers/did:example:123 HTTP/1.1 Accept: application/did-resolution
响应如下:
HTTP 200 OK
Content-Type: application/did-resolution
{
"didDocument": {
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
},
"didResolutionMetadata": {
"contentType": "application/did"
},
"didDocumentMetadata": {
...
}
}
可以通过 HTTP(S) 绑定按以下方式调用 resolve() 函数:
GET https://resolver.example/1.0/identifiers/did:example:123 HTTP/1.1 Accept: application/did
响应如下:
HTTP 200 OK
Content-Type: application/did
{
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
}
可以通过 HTTP(S) 绑定按以下方式调用 dereference() 函数:
GET https://resolver.example/1.0/identifiers/did:example:123?versionId=2 HTTP/1.1 Accept: application/did-url-dereferencing
响应如下:
HTTP 200 OK
Content-Type: application/did-url-dereferencing
{
"content": {
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
},
"dereferencingMetadata": {
"contentType": "application/did"
},
"contentMetadata": {
...
}
}
可以通过 HTTP(S) 绑定按以下方式调用 dereference() 函数:
GET https://resolver.example/1.0/identifiers/did:example:123?versionId=2 HTTP/1.1 Accept: application/did
响应如下:
HTTP 200 OK
Content-Type: application/did
{
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
}
DID resolution 和 DID URL dereferencing 不涉及任何身份验证或授权功能。类似于 DNS 解析,任何人都可以执行此过程,而无需任何凭证或非公开知识。
解释 DID 不一定是全局可解析的,例如成对或 N 方"对等"DID。
参见 [[RFC3339]]: URI 具有全局范围,无论上下文如何都以一致的方式解释,尽管解释的结果可能与最终用户的上下文有关。
一个高级想法是 DID 解析的结果可能是上下文相关的或依赖于策略,参见此评论。
一个相关主题是 DID 文档的(部分)是否可以加密,例如 w3c/did-core/issues/25。另请参见 IPID DID 方法中片段的使用。
DID resolver 可以维护 DID documents 的通用缓存。它也可以维护特定于某些 DID methods 的缓存。
noCache 解析选项可用于请求特定的缓存行为。
此解析选项是可选的(OPTIONAL)。
此属性的可能值为:
缓存行为可以通过 DID resolver 的配置、noCache 解析选项或 DID 文档内容(例如 `cacheMaxTtl` 字段)或这些属性的组合来控制。
实现 noCache 的解析器可能更容易受到拒绝服务攻击,因为恶意客户端可以绕过缓存来强制执行昂贵的网络请求和资源消耗。请求使用 noCache 进行解析的客户端应预期某些解析器会拒绝绕过缓存的解析请求。拒绝无缓存解析的解析器必须(MUST)响应 FEATURE_NOT_SUPPORTED 错误,明确表示不允许绕过缓存,以便客户端可以尝试不使用 noCache 进行解析。
如果从远程位置获取 JSON-LD 上下文文件,攻击者可能会篡改上下文文件(例如通过入侵服务器或通过中间人攻击拦截请求)。
因此,强烈建议执行远程 JSON-LD 上下文 URL 检索的任何 DID resolver 使用上下文文件及其对应哈希的注册表(或功能等效的机制)来帮助确保端到端安全性。预期实现如果资源的加密哈希值与预期哈希值不匹配则抛出错误。
如果提供了 versionId 或
versionTime DID 参数,DID resolution
算法会返回 DID document 的特定版本。
DID 参数 versionId
和 versionTime
是互斥的。
versionId DID 参数的使用是 DID method 特定的。其可能的值可能包括顺序号、随机 UUID、内容哈希等。
DID 文档元数据可以(MAY)包含一个 versionId
属性,该属性随对 DID 文档执行的每次 Update 操作而变化。
虽然大多数 DID methods 支持 Update 操作,但不要求 DID methods 保留所有先前的 DID document 版本,因此并非所有 DID methods 都支持版本控制。
使用分布式系统(如分布式账本)作为 VDR(verifiable data registry)的 DID methods 需要管理可能发生网络分叉的潜在风险。因此,使用分布式系统作为 VDR 的 DID method 规范应当(SHOULD)指定一种方式,以将其使用的 VDR 与此类分叉区分开来。
当 DID resolver 客户端解引用 DID document 中的标识符和链接资源时——特别是 verificationMethod、controller 或 alsoKnownAs 等字段——它可能会遇到 resolution cycle。当 DID document 引用另一个 DID(或 URL)最终导回先前解引用的标识符,形成循环时,就会发生这种情况。DID resolver 在解引用引用 service endpoint 的 DID URL 时也可能遇到这种情况。
did:example:alice
└── verificationMethod.controller → did:example:bob
└── verificationMethod.controller → did:example:alice
执行递归解引用的 DID resolvers 及其客户端应预期、检测和处理此类循环。
安全和性能风险:如果未检测和缓解循环,递归解引用可能导致:
缓解指导:递归跟踪外部 DID document 引用的组件应跟踪已经解引用的标识符,检测循环发生的时间并采取适当行动。此外,开发者可能希望限制递归深度或广度以减少潜在攻击面。
DID resolvers 和 DID URL dereferencers 将能够记录对其解析和解引用服务的请求。随着时间的推移,这些日志可能被用于跟踪和分析发出这些服务请求的客户端。为了缓解这种隐私风险,客户端应向其信任的服务发出此类请求,例如由于现有的业务关系或因为该服务运行在其控制的基础设施上。客户端还可以采取措施混淆其对服务的请求,以限制关联和画像分析的可能性。
用于将标识符解析为互联网地址的最常见机制之一是 [[?RFC1034]] 中描述的全球域名系统(DNS)。DNS 以及用于将域名映射到互联网协议地址的过程和系统是托管网站的常见需求。
[[[DID]]] 规范引入了一种不依赖全球域名系统的新型标识符,并引入了不需要集中化架构任何部分的标识符解析过程的概念。这种新架构允许去中心化地创建和管理全局可解析的标识符,以对抗标识符寻租和审查。它使个人能够完全拥有和控制其标识符,而不是从第三方租用标识符。
获取 [=DID URLs=] 的个人在其软件中使用它们,就像他们继续使用基于 DNS 的 URL 一样。软件使用 [=DID resolver=] 接口(在本规范中定义)来确定要检索的资源的位置。[=DID resolution=] 的过程,就像 DNS 解析的过程一样,对个人来说是不透明的,在软件内部发生而不需要个人的任何直接参与。
与 DNS 集中化相关的研究以及 [=DIDs=] 和 [=DID resolution=] 的相应发明记录在 [[[?DID]]] 规范中与 DID 的历史相关的章节中。