本规范描述了一种数据完整性加密套件,用于生成使用BBS签名方案的数字签名。 该签名套件利用BBS签名提供选择性披露和不可链接的派生证明。
工作组正在积极寻求对本规范的实施反馈。为了退出候选推荐阶段,工作组要求每个功能(包括强制性和可选功能)至少有两个独立的实现。有关一致性测试过程的详细信息,请参阅 实施报告。
本规范定义了一种加密套件,用于创建、验证和派生使用 BBS 签名方案的证明,以符合数据完整性 [[VC-DATA-INTEGRITY]] 规范。 BBS 签名方案直接提供选择性披露和不可链接的证明。它在 发行方、持有方、验证方 模型中提供了四个高级功能。具体来说,发行方使用 BBS 的 `Sign` 函数创建一种被称为“BBS 签名”的加密值,用于签署原始凭证。持有方在接收到使用 BBS 签名的凭证后,使用 BBS 的 `Verify` 函数验证该凭证。
持有方随后从接收到的凭证中选择性披露信息,并使用 BBS 的 `ProofGen` 函数生成一种被称为“BBS 证明”的加密值,用于为该“派生凭证”创建证明。加密的“BBS 证明”值无法链接到原始的“BBS 签名”,持有方可以为其他“派生凭证”生成不同的、不可链接的“BBS 证明”,即使这些凭证包含完全相同的信息。 最后,验证方使用 BBS 的 `ProofVerify` 函数验证从持有方接收到的派生凭证。
将 BBS 签名方案应用于可验证凭证涉及本文件中指定的处理过程。 通常,该套件使用 RDF 数据集规范化算法 [[RDF-CANON]] 将输入文档转换为其规范形式。发行方随后使用选择性披露原语将规范形式分为强制性和非强制性声明。这些声明与其他信息分开处理,作为 BBS `Sign` 函数的输入以及适当的密钥材料。此输出用于生成安全的凭证。持有方在接收到凭证后,使用一组选择性披露功能和 BBS 的 `Verify` 函数来验证凭证的有效性。
同样,在接收到 BBS 签名的凭证后,持有方使用 RDF 数据集规范化算法 [[RDF-CANON]] 将输入文档转换为其规范形式,然后应用选择性披露原语将规范形式分为强制性和选择性披露的声明,这些声明经过适当处理后作为 BBS `ProofGen` 函数的输入。经过适当处理后,该函数的输出成为发送给验证方的签名选择性披露凭证。使用规范化和选择性披露原语,验证方随后可以使用 BBS 的 `verifyProof` 函数验证凭证。
本文件中使用的术语在 [[[[VC-DATA-INTEGRITY]]]] 规范的 术语部分中定义。
符合性证明是符合本规范中的规范性声明的任何数据模型的具体表达形式。具体来说,本文件第 和 节中的所有相关规范性声明必须被强制执行。
符合性处理器是任何以软件和/或硬件实现的算法,用于生成或消费 符合性证明。符合性处理器在消费不符合规范的文档时必须产生错误。
本文件包含 JSON 和 JSON-LD 数据的示例。这些示例中有些是无效的 JSON,因为它们包含诸如内联注释(`//`)解释某些部分以及省略号(`...`)表示与示例无关的信息的省略等特性。如果实现者希望将这些示例视为有效的 JSON 或 JSON-LD,则需要移除这些部分。
以下部分概述了本规范中用于验证方法和数据完整性证明格式的数据模型。
这些验证方法用于验证使用符合 [[CFRG-BBS-SIGNATURE]] 的 BLS12-381 加密密钥材料生成的数据完整性证明 [[VC-DATA-INTEGRITY]]。本节提供了这些密钥类型的编码格式。在处理数字签名时,可以使用无损的加密密钥转换过程以生成等效的加密密钥材料。
多密钥格式,定义于 [[[CID]]],用于表示本规范中定义的加密套件的公钥。
`publicKeyMultibase` 属性表示 BLS12-381 G2 组中 381 位公钥的多基编码多密钥表达。
验证方法的 `publicKeyMultibase` 值必须以 base-58-btc 前缀 (`z`) 开头,如 [[[CID]]] 的 多基部分中定义。接下来是多基编码的 BLS12-381 381 位公钥值,如 [[[CID]]] 的 多密钥部分中定义。不允许使用任何其他编码。
开发者需注意不要意外发布私钥的表示形式。如果在 `publicKeyMultibase` 值中使用了 `0xeb01` 以外的多编解码值,本规范的实现将引发错误。
{ "id": "https://example.com/issuer/123#key-0", "type": "Multikey", "controller": "https://example.com/issuer/123", "publicKeyMultibase": "zUC7EK3ZakmukHhuncwkbySmomv3FmrkmS36E4Ks5rsb6VQSRpoCrx6 Hb8e2Nk6UvJFSdyw9NK1scFXJp21gNNYFjVWNgaqyGnkyhtagagCpQb5B7tagJu3HDbjQ8h 5ypoHjwBb" }
{ "@context": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1" ], "id": "https://example.com/issuer/123", "verificationMethod": [{ "id": "https://example.com/issuer/123#key-1", "type": "Multikey", "controller": "https://example.com/issuer/123", "publicKeyMultibase": "zUC7EK3ZakmukHhuncwkbySmomv3FmrkmS36E4Ks5rsb6VQSRpoCr x6Hb8e2Nk6UvJFSdyw9NK1scFXJp21gNNYFjVWNgaqyGnkyhtagagCpQb5B7tagJu3HDbjQ8h 5ypoHjwBb" }] }
证明包含 [[VC-DATA-INTEGRITY]] 的 证明部分中指定的属性,并具有以下限制。
证明的 `verificationMethod` 属性必须是一个 URL。解析 `verificationMethod` 必须返回一个包含 `type` 属性且值为 `Multikey` 的对象。
证明的 `type` 属性必须为 `DataIntegrityProof`。
证明的 `cryptosuite` 属性必须为 `bbs-2023`。
证明的 `proofValue` 属性的值必须是根据 [[CFRG-BBS-SIGNATURE]] 生成的 BBS 签名或 BBS 证明,并按照 部分中的程序进行序列化和编码。
以下算法描述了如何使用 BBS 签名方案 [[CFRG-BBS-SIGNATURE]] 处理可验证凭证。在使用 BBS 签名方案时,应使用 SHA-256 变体。
实现应尽早获取并缓存验证方法信息,以便在添加或验证证明时使用。本节中传递给函数的参数使用来自验证方法的信息(例如公钥大小)来确定函数参数(例如加密哈希算法)。
当使用 RDF 数据集规范化算法 [[RDF-CANON]] 时,该算法的实现将默认检测 数据集污染,并在检测到时中止处理。
此算法用于配置加密套件,以供 [[[VC-DATA-INTEGRITY]]] 中的 添加证明和 验证证明函数使用。该算法接受一个选项对象 ([=map=] |options|)作为输入,并返回一个[=数据完整性加密套件实例|加密套件实例=]([=struct=] |cryptosuite|)。
以下算法创建一个标签映射工厂函数,该函数使用 HMAC 对规范化的空白节点标识符进行混淆。所需输入是一个 HMAC(之前已使用密钥初始化),|HMAC|。输出是一个函数 labelMapFactoryFunction。
需要注意的是,上述算法中的步骤 1.2 与 [[DI-ECDSA]] 的 第 3.3.4 节 `createHmacIdLabelMapFunction` 中的步骤 1.2 相同,因此开发者在实现两者时可能可以重用代码或调用该函数。
以下算法序列化基础证明值,包括 BBS 签名、HMAC 密钥和强制性指针。 所需输入包括基础签名 |bbsSignature|、|bbsHeader|、|publicKey|、HMAC 密钥 |hmacKey|、一个数组 |mandatoryPointers|、|featureOption|,以及根据 |featureOption| 的值可能需要的 |signer_nym_entropy| 值。 输出是一个单一的 基础证明 字符串值。
以下算法解析 `bbs-2023` 选择性披露基础证明值的组成部分。所需输入为一个证明值(|proofValue|)。输出为一个包含六个或七个元素的单一对象,使用以下名称:"bbsSignature"、"bbsHeader"、"publicKey"、"hmacKey"、"mandatoryPointers"、"featureOption",以及可能的可选特性参数 "signer_nym_entropy"。
u
(U+0075
LATIN SMALL LETTER U
)
开头,表明它不是 `multibase-base64url-no-pad-encoded` 值,则必须引发错误,并应传递错误类型
PROOF_VERIFICATION_ERROR。
以下算法用于创建生成派生证明所需的数据。输入包括一个 JSON-LD 文档(|document|)、一个 BBS 基础证明(|proof|)、用于选择性披露声明的 JSON 指针数组(|selectivePointers|)、一个可选的 BBS |presentationHeader|(字节数组,默认为空字节数组)、一个 |featureOption| 指示器,以及 |featureOption| 所需的其他输入(参见 添加派生证明),以及任何自定义 JSON-LD API 选项(如文档加载器)。输出是一个单一对象,披露数据,包含以下字段:|bbsProof|、|labelMap|、|mandatoryIndexes|、|selectiveIndexes|、|presentationHeader|、|revealDocument|,以及(如果计算)|pseudonym|。
以下算法用于压缩标签映射。所需输入是标签映射(|labelMap|)。输出是一个压缩标签映射。
以下算法用于解压缩标签映射。所需输入是压缩标签映射(|compressedLabelMap|)。输出是一个解压缩标签映射。
以下算法用于序列化派生证明值。所需输入包括 BBS 证明(|bbsProof|)、标签映射(|labelMap|)、强制性索引数组(|mandatoryIndexes|)、选择性索引数组(|selectiveIndexes|)、BBS 展示头部(|presentationHeader|)、|featureOption| 指示器,以及根据 |featureOption| 值可能需要的 |nym_domain|、|pseudonym| 和/或 |lengthBBSMessages| 值。输出是一个序列化为字节字符串的单一派生证明值。
以下算法解析派生证明值的组成部分。所需输入为一个派生证明值(|proofValue|)。输出是一个单一的派生证明值对象,包含六到九个元素,名称为 "bbsProof"、"labelMap"、"mandatoryIndexes"、"selectiveIndexes"、"presentationHeader"、"featureOption",以及根据 |featureOption| 参数的值可能包含的 "nym_domain"、"pseudonym" 和/或 "lengthBBSMessages"。
u
(U+0075
,
LATIN SMALL LETTER U
)
开头,表明它不是 `multibase-base64url-no-pad-encoded` 值,则必须引发错误,并应传递错误类型
PROOF_VERIFICATION_ERROR。
以下算法用于创建验证 BBS 保护的可验证凭证所需的数据。输入包括一个 JSON-LD 文档(|document|)、一个 BBS 披露证明(|proof|)以及任何自定义 JSON-LD API 选项(如文档加载器)。输出是一个单一的验证数据对象,包含以下字段:|bbsProof|、|proofHash|、|mandatoryHash|、|selectiveIndexes|、|presentationHeader|、|nonMandatory|、|featureOption|,以及可能的 |pseudonym| 和/或 |lengthBBSMessages|。
`bbs-2023` 加密套件接收一个输入文档,使用 RDF 数据集规范化算法 [[RDF-CANON]] 对文档进行规范化,然后应用一系列转换和加密操作,最终生成一个数据完整性证明。本节中的算法还包括此类数据完整性证明的验证。
以下算法指定了如何根据未加密数据文档创建[=数据完整性证明=]。所需输入包括一个未加密数据文档([=map=] |unsecuredDocument|)、一组证明选项([=map=] |options|)、一个强制性 JSON 指针数组(|mandatoryPointers|)、一个 |featureOption| 指示参数,以及根据 |featureOption| 的值可能需要的 |commitment_with_proof| 字节数组。输出是一个[=数据完整性证明=]([=map=])或错误。
|featureOption| 参数用于指示是否使用了可选功能。它可以取以下值之一:`"baseline"`、`"anonymous_holder_binding"`、`"pseudonym"` 或 `"holder_binding_pseudonym"`。注意,`"baseline"` 表示未使用任何可选功能。如果 |featureOption| 设置为 `"anonymous_holder_binding"`、`"pseudonym"` 或 `"holder_binding_pseudonym"`,则必须提供 |commitment_with_proof| 输入。如果 |featureOption| 设置为 `"pseudonym"` 或 `"holder_binding_pseudonym"`,则必须提供 |signer_nym_entropy| 输入。
以下算法指定了如何将未加密的输入文档转换为一个已转换的文档,以便作为输入提供给第 节中的哈希算法。
此算法所需的输入包括一个未加密数据文档(|unsecuredDocument|)和转换选项(|options|)。转换选项必须包含加密套件的类型标识符(|type|)、加密套件标识符(|cryptosuite|)和验证方法(|verificationMethod|)。转换选项必须包含一个强制性 JSON 指针数组(|mandatoryPointers|),并且可以包含其他选项,例如 JSON-LD 文档加载器。输出是一个已转换数据文档。每当此算法对字符串进行编码时,必须使用 UTF-8 编码。
以下算法指定了如何对转换后的数据文档和证明配置进行加密哈希处理,以生成可作为输入提供给第 节中算法的加密哈希数据。
此算法所需的输入包括一个转换后的数据文档(|transformedDocument|)和规范化的证明配置(|canonicalProofConfig|)。输出是一个以对象表示的哈希数据值。
以下算法指定了如何从一组证明选项生成证明配置,以用作基础证明哈希算法的输入。
此算法所需的输入包括证明选项(|options|)和未加密数据文档(|unsecuredDocument|)。证明选项必须包含加密套件的类型标识符(|type|)和加密套件标识符(|cryptosuite|)。输出是一个证明配置对象。
以下算法由 BBS 保护的可验证凭证的发行方调用,指定如何创建基础证明。基础证明仅提供给持有方,持有方负责从中生成派生证明,并在证明中仅向验证方披露选择性披露的细节。此算法设计用于与数据完整性 [[VC-DATA-INTEGRITY]] 规范中定义的算法结合使用, 第 4 节:算法。所需输入包括加密哈希数据(|hashData|)、|featureOption|,以及(如果需要)|commitment_with_proof|。 如果 |featureOption| 设置为 `"anonymous_holder_binding"`、`"pseudonym"` 或 `"holder_binding_pseudonym"`,则必须提供 |commitment_with_proof| 输入;如果未提供,则必须引发错误,并应传递错误类型 PROOF_GENERATION_ERROR。 如果 |featureOption| 设置为 `"pseudonym"` 或 `"holder_binding_pseudonym"`,则必须提供 |signer_nym_entropy| 输入;如果未提供,则必须引发错误,并应传递错误类型 PROOF_GENERATION_ERROR。 输出是一个以字节表示的单一数字证明值。
以下算法由持有 `bbs-2023` 保护的可验证凭证的持有方调用,用于创建选择性披露的派生证明。派生证明将提供给验证方。输入包括一个 JSON-LD 文档(|document|)、一个 BBS 基础证明(|proof|)、一个用于选择性披露声明的 JSON 指针数组(|selectivePointers|)、一个可选的 BBS |presentationHeader|(字节数组)、一个 |featureOption| 参数、支持所选 |featureOption| 的附加参数(见下文),以及任何自定义 JSON-LD API 选项(如文档加载器)。输出是一个以对象表示的单一选择性披露文档值。
如果 |featureOption| 等于 `"anonymous_holder_binding"`,则必须提供附加输入 |holderSecret| 和 |proverBlind|。这些值由持有方预先计算。有关背景信息,请参阅匿名持有方绑定。
如果 |featureOption| 等于 `"pseudonym"`,则必须提供附加输入 |prover_nym| 和 |proverBlind|(两者均由持有方知晓),以及 |nym_dofmain|(由持有方设置或由验证方传递给持有方)。有关背景信息,请参阅凭证绑定的化名。
如果 |featureOption| 等于 `"holder_binding_pseudonym"`,则必须提供附加输入 |holder_secret|、|prover_nym| 和 |proverBlind|(均由持有方知晓),以及 |nym_dofmain|(由持有方设置或由验证方传递给持有方)。有关背景信息,请参阅持有方绑定和化名。
以下算法指定了如何验证给定安全数据文档的[=数据完整性证明=]。所需输入是一个安全数据文档([=map=] |securedDocument|)。此算法返回一个验证结果,它是一个[=struct=],其[=struct/items=] 包括:
要验证派生证明,请执行以下步骤:
BBS 签名的加密特性允许支持高级功能的变体。本规范仅限于支持这些增强功能中最相关的部分,我们将在以下章节中进行说明。变量 |commitment_with_proof|、|holder_secret|、|prover_nym|、|signer_nym_entropy| 和 |pseudonym| 与这些功能相关,而在 BBS 签名和证明中并不需要这些变量。
本节中描述的可选 BBS 功能以及本规范中的算法包含的功能存在风险,如果其各自的规范未能在 IETF 的时间表内达到 RFC 状态,或者每个可选功能没有至少两个独立的实现,这些功能将在本规范最终确定之前被移除。
此功能在签发时将带有基础证明的文档绑定到仅持有方知道的一个秘密,以确保只有该持有方能够生成可验证的带有派生证明的披露文档。例如,如果攻击者获得了带有基础证明的文档,他们无法创建可验证的带有派生证明的披露文档。
为了实现此功能,持有方生成一个 |holder_secret| 值,该值通常应至少为 32 字节长并通过加密随机生成。此值不会被持有方共享。相反,持有方生成一个承诺以及一个关于此值的零知识证明,使用 [[CFRG-Blind-BBS-Signature]] 的“承诺计算”操作。此计算涉及加密随机值,并计算出 |commitment_with_proof| 和 |secret_prover_blind| 值。|commitment_with_proof| 被传递给签发方,而 |secret_prover_blind| 被持有方保密并用于生成派生证明。 请注意,持有方可以多次运行“承诺计算”操作,以生成可用于不同签发方的不可链接的 |commitment_with_proof| 值。
签发方在收到 |commitment_with_proof| 后,按照本规范的程序,使用 [[CFRG-Blind-BBS-Signature]] 的“盲签名生成”操作生成文档的基础证明(签名),并使用持有方提供的 |commitment_with_proof|。
当持有方希望创建带有派生证明的选择性披露文档时,他们使用本规范的程序以及 [[CFRG-Blind-BBS-Signature]] 的“证明生成”操作。他们将其 |holder_secret| 作为 |committed messages| 数组中的唯一“消息”,并提供其 |secret_prover_blind|。
带有派生证明的披露文档的验证使用本规范的程序以及 [[CFRG-Blind-BBS-Signature]] 的“证明验证”操作。
本文件中指定的 BBS 签名的可验证凭证允许选择性披露和不可链接的加密证明工件。所谓“不可链接”,是指派生证明中的加密信息无法与其他证明或原始签名相关联。这意味着验证方无法确定持有方是否以前展示过相同的凭证(使用不同的证明实例),也无法断言某种身份。凭证绑定的化名提供了一种隐私保护机制,允许加密化名的有限链接性。此类化名可以由持有方单独确定,也可以由持有方和验证方共同确定。
这种加密化名(加密标识符/名称)由两部分组成。第一部分 |nym_secret| 由持有方指定并仅为持有方所知;第二部分 |nym_domain| 可以由持有方或验证方指定,并将在持有方和验证方之间共享。签发方在签发过程中将凭证绑定到 |nym_secret|。持有方随后可以从 |nym_secret| 计算化名,并向验证方证明这些化名绑定到他们正在展示的凭证。由相同 |nym_secret| 和不同 |nym_domain| 值计算出的加密化名是不可链接的。
持有方可能选择一个 |nym_domain|,为自己提供某种类型的公共论坛化名,例如选择 |nym_domain| = "Mark Twain"
。持有方从此 |nym_domain| 和其 |nym_secret| 计算出的加密化名本质上是唯一的,且没有同时知道 |nym_secret| 和拥有绑定到化名的基础可验证凭证的实体能够断言此化名身份。请注意,(|nym_domain|, 化名) 的二元组必须与派生凭证一起发送以断言此化名身份。
在另一种情况下,持有方可能正在使用验证方的服务,而验证方希望跟踪持有方的访问时间或监控其资源使用情况。在这种情况下,验证方选择持有方在展示其派生凭证时需要使用的 |nym_domain|。例如,验证方可能指定一个与其 DNS 域绑定的公共 |nym_domain|(例如 `"www.nym.example"`)供持有方使用。验证方还可以通过定期更改 |nym_domain|(例如将其与日期绑定,`"www.nym.example/2025-01-02"`)来展示其支持某种数据最小化的能力。本规范不规定 |nym_domain| 的值。
最后,为防止恶意持有方获取其他持有方的 |nym_secret| 并获得绑定到该值的凭证,[[CFRG-Pseudonym-BBS-Signature]] 的操作要求签发方在签名生成过程中添加一个随机化因子 |signer_nym_entropy|,该因子与持有方部分 |prover_nym| 安全地“混合”。这会生成一个 |nym_secret|,签发方可以为其提供加密保证,确保其唯一性并供持有方使用。
凭证绑定的化名的创建和使用概述如下步骤。
匿名持有方绑定和凭证绑定的化名在某种意义上是正交的功能,持有方和凭证生态系统可能希望同时使用这两种功能。例如,持有方可能希望将可验证凭证绑定到一个 |holder_secret|,以便只有知道该值的持有方才能从基础证明生成派生证明,并将一个 |nym_secret| 绑定到基础证明,以便化名可以绑定到派生证明。这对应于 |featureOption| 等于 `"holder_binding_pseudonym"`。
以下是同时使用匿名持有方绑定和凭证绑定化名的创建和使用步骤概述。
本节总结了“基础”BBS 证明以及可选功能的输入、输出、证明序列化、任务和过程。所谓基础BBS,是指没有附加功能的 BBS 基础证明和派生证明。所有可选功能都是“附加的”,意味着在“基础”BBS 签名/证明的基础上生成了一些额外的输入、任务或输出。
名称 | 任务 | 输入 | 签名算法 |
---|---|---|---|
基础 BBS | 基础:从 VC 生成 BBS 签名 | 基础:文档、证明选项、密钥材料、强制指针 | BBS |
匿名持有方绑定 | 基础 | 基础 + 来自持有方的带证明的承诺 | 盲 BBS |
凭证绑定的化名 | 基础 + 生成 |signer_nym_entropy| | 基础 + |signer_nym_entropy|,来自持有方的带证明的承诺 | 化名 BBS |
持有方绑定和化名 | 基础 + 生成 |signer_nym_entropy| | 基础 + |signer_nym_entropy|,来自持有方的带证明的承诺 | 化名 BBS |
名称 | 证明头部字节 | 序列化输出 |
---|---|---|
基础 BBS | `0xd9`,`0x5d`,和 `0x02` | 基础:bbsSignature,bbsHeader,publicKey,hmacKey 和 mandatoryPointers |
匿名持有方绑定 | `0xd9`,`0x5d`,和 `0x04` | 基础 |
凭证绑定的化名 | `0xd9`,`0x5d`,和 `0x06` | 基础 + |signer_nym_entropy| |
持有方绑定和化名 | `0xd9`,`0x5d`,和 `0x08` | 基础 + |signer_nym_entropy| |
名称 | 任务 | 输入 | 证明生成算法 |
---|---|---|---|
基础 BBS | 从 VC 和基础证明生成 BBS 派生证明 | 基础:从基础证明序列化中获取 bbsSignature,bbsHeader,publicKey,hmacKey 和 mandatoryPointers;选择性指针(持有方选择) | BBS |
匿名持有方绑定 | 基础 | 基础 + |holder_secret|,|prover_blind|(均为持有方已知) | 盲 BBS |
凭证绑定的化名 | 基础 + 计算 |nym_secret|,计算 |pseudonym| | 基础 + |prover_nym|,|prover_blind|(均为持有方已知),|signer_nym_entropy|(由发行方包含在基础中),|nym_domain| | 化名 BBS |
持有方绑定和化名 | 基础 + 计算 |nym_secret|,计算 |pseudonym| | 基础 + |holder_secret|,|prover_nym|,|prover_blind|(均为持有方已知),|signer_nym_entropy|(由发行方包含在基础中),|nym_domain| | 化名 BBS |
名称 | 证明头部字节 | 序列化输出 |
---|---|---|
基础 BBS | `0xd9`,`0x5d`,和 `0x03` | 基础:bbsProof,compressedLabelMap,mandatoryIndexes,selectiveIndexes,presentationHeader |
匿名持有方绑定 | `0xd9`,`0x5d`,和 `0x05` | 基础 |
凭证绑定的化名 | `0xd9`,`0x5d`,和 `0x07` | 基础 + |pseudonym|,|nym_domain| |
持有方绑定和化名 | `0xd9`,`0x5d`,和 `0x09` | 基础 + |pseudonym|,|nym_domain| |
名称 | 输入 | 证明验证算法 |
---|---|---|
基础 BBS | 基础:从派生证明序列化中获取 bbsProof,compressedLabelMap,mandatoryIndexes,selectiveIndexes,presentationHeader | BBS |
匿名持有方绑定 | 基础 | 盲 BBS |
凭证绑定的化名 | 基础 + |pseudonym|(包含在派生证明中),|nym_domain| | 化名 BBS |
持有方绑定和化名 | 基础 + |pseudonym|(包含在派生证明中),|nym_domain| | 化名 BBS |
在阅读本节之前,建议读者先熟悉 数据完整性规范的安全性考虑部分中提供的一般安全建议。
基础证明的安全性依赖于相关的BBS 签名的安全属性。数字签名可能具有许多理想的加密属性 [[Taming_EdDSAs]],其中包括:
EUF-CMA(在选择消息攻击下的存在性不可伪造性)通常是签名方案所需的最低安全属性。它保证任何拥有签名者公钥的高效攻击者 并接收任意数量的消息签名(以自适应方式选择消息): , 无法输出一个有效的签名 用于一条新消息 (除非概率极小)。如果攻击者对一条新消息输出了一个有效签名: , 则称之为存在性伪造。
SUF-CMA(在选择消息攻击下的强不可伪造性)是比EUF-CMA更强的概念。它保证任何拥有签名者公钥的高效攻击者 并接收任意数量的消息签名: , 无法输出一个新的有效签名对 , 使得 (除非概率极小)。强不可伪造性意味着攻击者不仅无法对新消息签名,也无法对旧消息找到新的签名。
在 [[CDL2016]] 中,在一些合理的假设下,BBS 签名被证明是 EUF-CMA 的。此外,在 [[TZ2023]] 中,在类似假设下,BBS 签名被证明是 SUF-CMA 的。这两种情况下的假设都与离散对数问题的难度相关,而该问题在大规模量子计算条件下不被认为是安全的。
在非量子计算条件下,[[CFRG-BBS-SIGNATURE]] 为 BBS 签名套件的实现者提供了额外的安全指南。与配对友好曲线相关的进一步安全性考虑在 [[CFRG-PAIRING-FRIENDLY]] 中讨论。
派生证明的安全性依赖于相关的BBS 证明的安全属性。[[CDL2016]] 和 [[TZ2023]] 都证明了BBS 证明是对 BBS 签名知识的零知识证明
。
如 [[CFRG-BBS-SIGNATURE]] 中所述,这意味着:
接收到证明的验证方无法确定用于生成该证明的签名,从而消除了常见的关联来源。通常,即使是从同一签名生成的两个证明,每个生成的证明也与随机值无法区分。
并且
该方案生成的证明向验证方证明生成证明的一方(持有方/证明方或其代理)拥有签名,但未透露签名本身。
更具体地说,验证BBS 证明需要原始签发方的公钥以及按正确顺序排列的未修改的、已披露的BBS 消息。
选择性披露允许持有方根据特定目的最小化向验证方披露的信息。在设计支持选择性披露的整体系统时,必须注意尽量减少未计划向验证方披露的额外信息。这种泄漏可能通过系统的工件发生。这些工件可能来自系统的更高层(例如数据结构)或更低层的密码学原语。
例如,BBS签名方案是一种极其高效的方案,用于对多个消息生成签名,即发送给持有方的密码学签名的大小是固定的,与消息的数量无关。持有方随后可以选择性地向验证方披露这些消息中的任意部分,但作为加密方案的一部分,签发方签署的消息总数必须向验证方披露。如果需要避免此类信息泄漏,建议按照[[CFRG-BBS-SIGNATURE]]隐私注意事项部分的建议,将消息数量填充到一个通用长度。
在更高层次上,如何将数据映射到适合选择性披露的单个声明(即BBS消息)可能是数据泄漏的潜在来源。此加密套件能够通过使用JSON-LD处理将输入转换为RDF,消除许多可能泄漏信息的JSON数据结构工件(如嵌套、映射或数组位置等)。RDF可以被表达为规范化的、简单的主体-属性-值声明(在可验证凭证数据模型[[VC-DATA-MODEL-2.0]]中称为声明)。在以下内容中,我们将研究RDF规范化,这是一种将JSON-LD格式的可验证凭证映射为一组声明(BBS消息)的通用方案,用于选择性披露。我们将展示在执行此过程后,仍然存在可能的信息泄漏来源,并展示如何通过使用密钥伪随机函数(PRF)来缓解这种泄漏。
RDF规范化可用于将JSON-LD可验证凭证扁平化
为一组声明。该算法依赖于可验证凭证的内容,并使用密码学哈希函数帮助对声明进行排序。本质上,这一过程是将JSON对象(表示JSON-LD文档中声明的主体)分配一个id(如果未定义`@id`字段)。这些id被称为空白节点id。这些id用于将声明表达为简单的主体-属性-值声明,以便可以区分每个声明中的主体。id值根据[[RDF-CANON]]的规范化算法以及文档中的数据和密码学哈希函数(如SHA-256)的输出确定。
以下展示了两组稍有不同的风帆可验证凭证及其规范化为一组可用于选择性披露的声明。通过更改6.1尺寸风帆的年份,我们可以看到这两组凭证之间的声明排序发生了重大变化。如果持有方仅披露其较大尺寸的风帆(7.0和7.8)的信息,验证方可能会发现风帆集合发生了变化,即信息泄漏。
{ "@context": [ "https://www.w3.org/ns/credentials/v2", { "@vocab": "https://windsurf.grotto-networking.com/selective#" } ], "type": [ "VerifiableCredential" ], "credentialSubject": { "sails": [ { "size": 5.5, "sailName": "Kihei", "year": 2023 }, { "size": 6.1, "sailName": "Lahaina", "year": 2023 // 将更改此处以查看对规范化的影响 }, { "size": 7.0, "sailName": "Lahaina", "year": 2020 }, { "size": 7.8, "sailName": "Lahaina", "year": 2023 } ] } }
上述可验证凭证的规范化形式。空白节点id的分配(即_:c14nX
标签)依赖于可验证凭证的内容,这也会影响声明的排序。
_:c14n0 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n0 <https://windsurf.grotto-networking.com/selective#size> "7.8E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n0 <https://windsurf.grotto-networking.com/selective#year> "2023"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> . _:c14n1 <https://www.w3.org/2018/credentials#credentialSubject> _:c14n4 . _:c14n2 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n2 <https://windsurf.grotto-networking.com/selective#size> "7"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n2 <https://windsurf.grotto-networking.com/selective#year> "2020"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n3 <https://windsurf.grotto-networking.com/selective#sailName> "Kihei" . _:c14n3 <https://windsurf.grotto-networking.com/selective#size> "5.5E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n3 <https://windsurf.grotto-networking.com/selective#year> "2023"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n4 <https://windsurf.grotto-networking.com/selective#sails> _:c14n0 . _:c14n4 <https://windsurf.grotto-networking.com/selective#sails> _:c14n2 . _:c14n4 <https://windsurf.grotto-networking.com/selective#sails> _:c14n3 . _:c14n4 <https://windsurf.grotto-networking.com/selective#sails> _:c14n5 . _:c14n5 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n5 <https://windsurf.grotto-networking.com/selective#size> "6.1E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n5 <https://windsurf.grotto-networking.com/selective#year> "2023"^^<http://www.w3.org/2001/XMLSchema#integer> .
更新后的风帆集合,即6.1尺寸的风帆已更新为2024型号。这通过空白节点id的分配改变了声明的排序。
{ "@context": [ "https://www.w3.org/ns/credentials/v2", { "@vocab": "https://windsurf.grotto-networking.com/selective#" } ], "type": [ "VerifiableCredential" ], "credentialSubject": { "sails": [ { "size": 5.5, "sailName": "Kihei", "year": 2023 }, { "size": 6.1, "sailName": "Lahaina", "year": 2024 // 新风帆以更新旧型号,改变了规范化 }, { "size": 7.0, "sailName": "Lahaina", "year": 2020 }, { "size": 7.8, "sailName": "Lahaina", "year": 2023 } ] } }
上述可验证凭证的规范化形式。注意空白节点id分配和声明排序的差异。
_:c14n0 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n0 <https://windsurf.grotto-networking.com/selective#size> "6.1E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n0 <https://windsurf.grotto-networking.com/selective#year> "2024"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n1 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n1 <https://windsurf.grotto-networking.com/selective#size> "7.8E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n1 <https://windsurf.grotto-networking.com/selective#year> "2023"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> . _:c14n2 <https://www.w3.org/2018/credentials#credentialSubject> _:c14n5 . _:c14n3 <https://windsurf.grotto-networking.com/selective#sailName> "Lahaina" . _:c14n3 <https://windsurf.grotto-networking.com/selective#size> "7"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n3 <https://windsurf.grotto-networking.com/selective#year> "2020"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n4 <https://windsurf.grotto-networking.com/selective#sailName> "Kihei" . _:c14n4 <https://windsurf.grotto-networking.com/selective#size> "5.5E0"^^<http://www.w3.org/2001/XMLSchema#double> . _:c14n4 <https://windsurf.grotto-networking.com/selective#year> "2023"^^<http://www.w3.org/2001/XMLSchema#integer> . _:c14n5 <https://windsurf.grotto-networking.com/selective#sails> _:c14n0 . _:c14n5 <https://windsurf.grotto-networking.com/selective#sails> _:c14n1 . _:c14n5 <https://windsurf.grotto-networking.com/selective#sails> _:c14n3 . _:c14n5 <https://windsurf.grotto-networking.com/selective#sails> _:c14n4 .
为了防止这些空白节点id的分配及其对声明排序的影响导致的信息泄漏,会对空白节点id运行基于HMAC的伪随机函数(PRF)。HMAC密钥仅在签发方和持有方之间共享,并且每个由签发方生成的基础证明都会使用一个新的HMAC密钥。可以在[[DI-ECDSA]]的规范化HMAC测试向量中看到此示例。
如下一节所述,为了使BBS保持不可链接性,我们不使用基于HMAC的空白节点id,而是基于HMAC生成打乱
版本的排序,如测试向量所示。请注意,与ECDSA-SD方法相比,这种方法在空白节点id方面提供的信息隐藏较少,因为空白节点id的数量可能会泄漏,但通过对空白节点id应用HMAC生成的本质上唯一的标识符,可以防止链接攻击。
在某些可验证凭证(VC)的使用场景中,为了保护持有方的隐私,防止多个不同验证方交互的跟踪或关联可能非常重要。特别是,我们考虑两种重要情况:(i) 验证方与签发方串通,以及 (ii) 验证方与验证方串通。在第一种情况下,如所示,验证方向凭证的原始签发方报告与持有方的交互。在这种情况下,签发方可以通过已签发的VC跟踪持有方与各种验证方的所有交互。在第二种情况下,如所示,多个验证方串通共享他们与持有方交互的信息。
我们使用术语不可链接性来描述VC系统防止此类“关联攻击”对持有方隐私的能力。尽管“不可链接性”这一术语相对较新,但[[NISTIR8053]]的第3.3节讨论并提供了一个关于通过关联攻击重新识别
的案例研究。关于数据隐私关联攻击
的知识系统化可以在[[Powar2023]]中找到。最广泛使用的用户隐私关联攻击发生在网络浏览器指纹识别的实践中,其调查可以在[[Pugliese2020]]中找到。
为了量化关联的概念,[[Powar2023]]引入了匿名集的概念。在我们关心的VC场景中,匿名集将包含特定VC的持有方以及与特定签发方相关的其他持有方。匿名集越小,持有方越可能被验证方跟踪。由于签名的VC包含对签发方公钥的引用,对于持有特定签发方VC的持有方来说,匿名集的初始大小是该签发方使用特定公/私钥对签发的VC数量。非恶意的签发方应尽量减少用于签发VC的公/私钥对的数量。请注意,匿名集的概念类似于[[vc-bitstring-status-list]]中的群体隐私概念。当我们在此使用“关联”一词时,通常是指任何导致匿名集大小减少的机制。
支持选择性披露的VC系统中的关联来源:
我们将在下文中讨论这些内容。
密码学哈希、HMAC和数字签名本质上会生成高度唯一的标识符。诸如SHA-256之类的哈希函数的输出,由于其抗碰撞特性,保证在不同输入下本质上是唯一的,从而导致强关联,即将匿名集大小减少为1。同样,诸如Ed25519和确定性ECDSA之类的确定性签名算法会为不同输入生成本质上唯一的输出,并导致强关联。
这意味着持有方可以通过VC中的数字签名、HMAC或哈希工件轻松地在验证方之间被跟踪,因此容易受到验证方-验证方串通和验证方-签发方串通的攻击。某些形式的ECDSA等随机化签名算法可以允许签发方为相同输入生成许多不同的签名,并将这些签名发送给持有方以供不同的验证方使用。这种方法可以用来防止基于验证方-验证方串通的跟踪,但无法防止验证方-签发方串通。
要实现不可链接性,需要专门设计的密码学签名方案,允许持有方生成所谓的签名知识的零知识证明
(ZKPKS)。这意味着持有方可以在此类方案中从签发方获取签名,计算一个ZKPKS并将其发送给验证方。此ZKPKS无法链接回原始签名,但具有签名的所有理想属性,即验证方可以使用它来验证消息是否由签发方的公钥签名,以及消息是否未被篡改。此外,持有方可以为不同的验证方生成任意数量的ZKPKS,这些ZKPKS本质上是独立且不可链接的。BBS是一种支持此功能的签名方案。
尽管文档中称为BBS证明的ZKPKS具有保证的不可链接性属性,但BBS在与选择性披露一起使用时有两个工件可能导致关联。这些工件是最初签名的消息总数和披露声明的索引值。有关讨论和缓解技术,请参阅[[CFRG-BBS-SIGNATURE]]中的隐私注意事项。
如[[CFRG-BBS-SIGNATURE]]的签发方的公钥
部分所述,存在一种潜在威胁,即签发方可能使用多个公钥,其中一些用于通过验证方-签发方串通跟踪特定用户子集。由于签发方的公钥必须对验证方可见,即它在BBS证明(派生证明)中被引用,如果签发方有许多不同的公钥,特别是如果它对一小部分用户(持有方)使用这些公钥的子集,这可能被用作关联点。
我们在信息泄漏部分看到,RDF规范化使用哈希函数对声明进行排序,并基于HMAC对声明的顺序进行进一步的打乱
。这可能会留下指纹,从而允许某种程度的关联。关联的强度取决于VC中空白节点(本质上是JSON对象)的数量以及披露的索引数量。给定n个空白节点和k个披露的索引,在最坏情况下,这将导致匿名集大小减少一个因子C(n, k),即从n个元素的集合中选择大小为k的组合数。通过减少VC中的空白节点数量,例如保持VC简短和简单,可以将此数字保持在较低水平。
JSON-LD是一种基于JSON的格式,用于序列化关联数据。因此,它支持为文档中的每个对象(在JSON-LD术语中称为“节点”)分配一个全局唯一的`@id`属性(节点标识符)。这允许关联数据的链接
,从而使关于同一实体的信息可以被关联。这种关联可能是可取的,也可能是不可取的,具体取决于使用场景。
在使用BBS的不可链接性功能时,不能为个人或其个人身份信息使用全局唯一的节点标识符,因为它们提供的强关联是不可取的。请注意,当表达关于非个人信息的声明时(例如,使用全局唯一标识符来标识一个大国或一场音乐会活动),使用此类标识符是可以接受的。另外请注意,JSON-LD使用的`@context`,将术语映射到IRI,通常不会影响不可链接性。
在[[vc-data-integrity]]规范中,给出了VC的`proof`属性的许多属性。需要注意的是,可选字段不应在验证方之间提供强关联。这些可选字段包括:id、created、expires、domain、challenge和nonce。例如,可选的created字段是一个`dateTimeStamp`对象,可以指定证明的创建日期,精确到任意的亚秒级粒度。如果存在此类信息,可能会大大减少匿名集的大小。如果签发方希望包含此类信息,则应尽可能使其粒度较粗,相对于一段时间内签发的VC数量。
签发方还可以通过在创建基础证明时使用的`mandatoryPointers`输入,强制持有方向验证方披露某些声明。请参阅、和部分。通过强制
,我们指的是生成的派生证明在未向验证方披露这些声明时将无法验证。应注意,如果要求披露此类信息,匿名集应保持足够大。
如[[Powar2023]]所述,有许多关于通过关联攻击重新识别个人的案例。因此,建议持有方尽可能少地披露信息,以帮助保持匿名集的大小。此外,已经多次证明,看似无害的信息可能具有高度的唯一性,从而导致重新识别或跟踪。请参阅[[NISTIR8053]],了解关于马萨诸塞州前州长的一个特别著名案例的详细说明,以及[[Powar2023]]中对94个此类公开案例的进一步分析和分类。
需要指出的是,保持不可链接性(即匿名性)需要在持有和传输VC的系统中小心处理。网络工件(如IP地址(第3层)或以太网/MAC地址(第2层))是众所周知的关联来源。例如,如果移动电话的MAC地址在重新访问特定接入点时被使用,这可能会导致用户被跟踪,这促使移动电话制造商提供了MAC地址随机化功能。公共IP地址通常提供足够的信息,可以将个人定位到一个城市或国家内的区域,从而可能大大减少匿名集的大小。
文档测试向量基于一个完全虚构的永久居民卡,并分为两组——由签发方生成的(“基础证明”)和由持有方生成的(“派生证明”)。
要向文档添加选择性披露的基础证明,签发方需要以下加密密钥材料:
用于生成测试向量以测试添加基础证明的密钥材料如下所示。BBS 密钥对和 HMAC 密钥使用十六进制表示。
在我们的场景中,将签发永久居民凭证。未签名的永久居民文档如下所示。
此强制性信息通过一个 JSON 指针数组指定,如下所示。
将上述 JSON 指针应用于文档的结果如下所示。
未签名文档的转换从文档规范化开始,如下所示。
为了防止通过空白节点 ID 的排序可能导致的信息泄漏,这些 ID 通过 PRF(即 HMAC)处理,生成如下所示的规范化 HMAC 文档。这表示将根据披露要求分组的声明的有序列表,这些声明在分组后仍将按此列表中的顺序排列。
上述规范化文档中的列表被分为强制性和非强制性声明。选择性披露转换过程的最终输出如下所示。请注意,这些声明现在被分组为强制性或非强制性披露,并且记住了每个声明在前一列表中的索引。
下一步是创建基础证明配置并对其进行规范化。以下是两个示例。
在哈希步骤中,我们计算规范化证明选项的 SHA-256 哈希以生成 `proofHash`,并计算所有强制性 N-Quads 的 `JOIN` 的 SHA-256 哈希以生成 `mandatoryHash`。以下以十六进制格式显示。
下面显示了以十六进制表示的计算出的 `bbsSignature` 和 `mandatoryPointers`。这些被作为最终序列化步骤的输入,与 `hmacKey` 一起使用。
随机数被使用,并且可选的 `presentationHeader` 可以作为附加输入,用于创建 BBS 证明
。为了提供一组确定性的测试向量,我们使用了 [[CFRG-BBS-SIGNATURE]] 中的 模拟随机标量
程序。我们用于生成派生证明测试向量的 `seed` 和 `presentationHeader` 值如下所示(以十六进制表示)。
要创建派生证明,持有方从包含基础证明的签名文档开始。我们将用于这些测试向量的基础文档是上述第 节中的最终示例。第一步是运行第 节的算法以恢复 `bbsSignature`、`hmacKey` 和 `mandatoryPointers`,如下所示。
接下来,持有方需要指明是否希望向验证方披露任何非强制性声明,通过指定选择性披露的 JSON 指针。这些如下所示。
为了生成 `revealDocument`(即最终将被签名并发送给验证方的未签名文档),我们将选择性指针附加到强制性指针,并将这些组合指针与不包含证明的文档一起输入到 [[DI-ECDSA]] 的 `selectJsonLd` 算法中。结果如下所示。
现在我们知道披露文档的样子了,我们需要向验证方提供适当更新的信息,说明哪些声明是强制性的,以及所选非强制性声明的索引。运行第 节的第 6 步会生成关于原始文档中各种声明组的大量信息。以下显示了这些组的索引部分。
验证方需要能够聚合和哈希强制性声明。为此,我们向他们提供了强制性声明的索引列表,这些索引相对于披露文档中的位置进行了调整(即相对于 `combinedIndexes`),而 `selectiveIndexes` 则相对于它们在 `nonMandatoryIndexes` 中的位置进行了调整。这些“调整后”的索引如下所示。
最后一个重要的披露数据是 `labelMap`,它是规范化空白节点 ID 到基于 HMAC 的随机化 ID 的映射,根据第 节计算。以下显示了此映射以及其余的披露数据(不包括披露文档)。
展示选择性披露功能,包括强制披露、选择性披露以及两者的重叠,要求输入的凭证文档比之前的测试向量包含更多内容。为了避免测试向量过长,起始文档测试向量基于一个完全虚构的风帆(帆船)比赛场景。此外,我们将测试向量分为两组,一组由签发方生成(基础证明),另一组由持有方生成(派生证明)。
要向文档添加选择性披露的基础证明,签发方需要以下加密密钥材料:
用于生成测试向量以测试添加基础证明的密钥材料如下所示。BBS 密钥对和 HMAC 密钥使用十六进制表示。
在我们的场景中,一名水手正在向比赛组织者注册参加将在毛伊岛举行的多日风帆比赛系列。组织者将检查水手的设备以确认所声明的内容是否准确。水手的未签名设备清单如下所示。
除了让其他水手了解他们的竞争对手可能使用的设备类型外,每名水手还必须披露其最近的风帆板的年份以及两块帆的完整详细信息。请注意,所有水手都通过印在其所有设备上的帆号进行标识。此强制性信息通过一个 JSON 指针数组指定,如下所示。
将上述 JSON 指针应用于水手的设备文档的结果如下所示。
未签名文档的转换从文档规范化开始,如下所示。
为了防止通过空白节点 ID 的排序可能导致的信息泄漏,这些 ID 通过 PRF(即 HMAC)处理,生成如下所示的规范化 HMAC 文档。这表示将根据披露要求分组的声明的有序列表,这些声明在分组后仍将按此列表中的顺序排列。
上述规范化文档中的列表被分为强制性和非强制性声明。选择性披露转换过程的最终输出如下所示。请注意,这些声明现在被分组为强制性或非强制性披露,并且记住了每个声明在前一列表中的索引。
下一步是创建基础证明配置并对其进行规范化。以下是两个示例。
在哈希步骤中,我们计算规范化证明选项的 SHA-256 哈希以生成 `proofHash`,并计算所有强制性 N-Quads 的 `JOIN` 的 SHA-256 哈希以生成 `mandatoryHash`。以下以十六进制格式显示。
下面显示了以十六进制表示的计算出的 `bbsSignature` 和 `mandatoryPointers`。这些被作为最终序列化步骤的输入,与 `hmacKey` 一起使用。
使用匿名持有者绑定功能的第一步是持有者生成其|holderSecret|值,然后根据[[CFRG-Blind-BBS-Signature]]的承诺计算过程计算一个带有证明的承诺。以下是此过程的示例值和输出。
|holderSecret|和|secretProverBlind|应由持有者保留并保密。|commitmentWithProof|值应传递给签发方。
在匿名持有者绑定选项下添加基础证明的过程从签发方接收持有者的|commitmentWithProof|值并使用[[CFRG-Blind-BBS-Signature]]的承诺验证过程验证该值开始。 第基础证明部分中解释和使用的加密密钥材料也将在此处使用,并在下方重复。
在此场景中,我们考虑电子版的驾驶执照。
为了保护持有者的隐私,唯一的强制性字段是“issuer”和“expirationDate”,如以下强制性指针所示。
未签名文档的转换从文档规范化开始,如下所示。
为了防止空白节点 ID 的排序可能导致的信息泄漏,这些 ID 通过 PRF(即 HMAC)处理,生成如下所示的规范化 HMAC 文档。这表示将根据披露要求分组的声明的有序列表,这些声明在分组后仍将按此列表中的顺序排列。
上述规范化文档被分为强制性和非强制性声明。选择性披露转换过程的最终输出如下所示。每个声明现在被分组为强制性或非强制性,并记住了其在前一列表中的索引。
下一步是创建基础证明配置并对其进行规范化。以下是两个示例。
在哈希步骤中,我们计算规范化证明选项的 SHA-256 哈希以生成|proofHash|,并计算所有强制性 N-Quads 的连接的 SHA-256 哈希以生成`mandatoryHash`。以下以十六进制格式显示。
现在我们使用[[CFRG-Blind-BBS-Signature]]的盲签名生成过程,在 过程中。 以下显示了计算出的|bbsSignature|、|bbsHeader|、|publicKey|、 |hmacKey|、|mandatoryPointers|和|featureOption|,其中字节数据以十六进制显示。
如第节所述,我们使用模拟的随机数生成过程并演示了|presentationHeader|的使用。这里使用了相同的|seed|和|presentationHeader|,并在下方重复。
为了创建派生证明,持有者从包含基础证明的签名文档开始。我们将用于这些测试向量的基础文档是上述第节的最终示例。 第一步是运行第节的算法以 恢复|bbsSignature|、|bbsHeader|、|publicKey|、|hmacKey|、 |mandatoryPointers|和|featureOption|,如下所示。
接下来,持有者需要指明他们希望向验证方披露的其他内容(如果有),通过指定选择性披露的 JSON 指针。在此情况下,持有者仅希望披露其驾驶权限。
为了生成`revealDocument`(即最终将签名并发送给验证方的未签名文档),我们将选择性指针附加到强制性指针,并将这些组合指针与不包含证明的文档一起输入到[[DI-ECDSA]]的`selectJsonLd`算法中,得到如下结果。
现在我们知道披露文档的样子了,我们需要向验证方提供适当更新的信息,说明哪些声明是强制性的,以及所选非强制性声明的索引。运行第 节的第 6 步会生成关于相对于原始文档的各种声明组的大量信息。下方显示了这些组的索引部分。
验证方需要能够聚合和哈希强制性声明。为了实现这一点,我们向他们提供了强制性声明的索引列表,这些索引相对于披露文档中的位置进行了调整(即相对于`combinedIndexes`),而`selectiveIndexes`需要相对于`nonMandatoryIndexes`中的位置进行调整。这些“调整后”的索引如下所示。
披露数据的最后一个重要部分是规范化空白节点 ID 到基于 HMAC 的打乱 ID 的映射,即`labelMap`,根据第 节计算。下方显示了此映射以及披露数据的其余部分(不包括披露文档)。请注意,这里显示的结果适用于|featureOption|等于`"anonymous_holder_binding"`的情况,该选项使用[[CFRG-Blind-BBS-Signature]]的盲证明生成过程。请注意,|blindAdjDisclosedIdxs|是证明序列化过程中使用的最终 BBS 选择性索引集,来自盲 BBS 证明生成函数,该函数以|adjSelectiveIndexes|作为输入。
使用凭证绑定的化名功能的第一步是持有者生成其秘密值|prover_nym|,然后根据[[CFRG-Pseudonym-BBS-Signature]]的“承诺”操作计算一个带有证明的承诺。以下是此过程的示例值和输出。
|prover_nym|和|secretProverBlind|应由持有者保留并保密。|commitmentWithProof|值应传递给签发方。
在化名功能选项下添加基础证明的过程从签发方接收持有者的|commitmentWithProof|值并生成一个加密随机值|signer_nym_entropy|开始。
本示例将使用与中显示的相同密钥材料,与中显示的相同未签名文档,以及与中显示的相同强制性指针。这将生成与中显示的相同规范化文档,与中显示的相同规范化 HMAC 文档,以及与中显示的相同“添加基础转换”。
本示例使用与中相同的证明配置。这将生成与中相同的规范化基础证明。结合上述假设,将生成与中相同的基础哈希。
由于|featureOption|等于`"pseudonym"`,第节的过程将生成如下所示的输出。这使用了[[CFRG-Pseudonym-BBS-Signature]]的签名生成算法。请注意包含|signer_nym_entropy|和|featureOption|值,这些值需要传递给持有者。
如第节所述,我们使用模拟的随机数生成过程来演示|presentationHeader|的使用。这里使用了与中给出的相同|seed|和|presentationHeader|。
为了创建派生证明,持有者从包含基础证明的签名文档开始。我们将用于这些测试向量的基础文档是上述中的最终示例。第一步是运行第节的算法以恢复|bbsSignature|、|bbsHeader|、|publicKey|、|hmacKey|、|mandatoryPointers|、|signer_nym_entropy|和|featureOption|,如下所示。
接下来,持有者使用[[CFRG-Pseudonym-BBS-Signature]]的“验证和最终化”操作来验证签名并计算|nym_secret|值。此操作使用|prover_nym|、|signer_nym_entropy|和|secret_prover_blind|值等。
接下来,持有者需要指明他们希望向验证方披露的非强制性声明(如果有),通过指定选择性披露的 JSON 指针。在此情况下,持有者披露了与中给出的相同信息。这将生成与中显示的相同|revealDocument|。
运行会生成与中显示的相同派生组索引信息,以及与中显示的相同调整后的强制性和选择性索引。
在中,我们基于中显示的相同|verfifier_id|计算|pseudonym|。的最终输出如下所示。请注意包含|featureOption|和计算的|pseudonym|值。
使用持有者绑定和化名功能的第一步是持有者生成其|holder_secret|和|prover_nym|值, 然后根据[[CFRG-Pseudonym-BBS-Signature]]的“承诺”操作计算一个带有证明的承诺。以下是此过程的示例值和输出。
|holder_secret|、|prover_nym|和|secretProverBlind|需要由持有者保留并保密。|commitmentWithProof|值需要传递给签发方。
在化名功能选项下添加基础证明的过程从签发方接收持有者的|commitmentWithProof|值并生成一个加密随机值|signer_nym_entropy|开始。
此示例将使用与 中显示的相同密钥材料, 以及与中显示的相同未签名文档, 以及与中显示的相同强制性指针。 这将生成与中显示的相同规范文档, 与中显示的相同规范HMAC文档, 以及与中显示的相同“添加基础转换”。
此示例使用与中相同的证明配置。 这将生成与中相同的规范基础证明。 结合上述假设,生成与中相同的基础哈希。
由于|featureOption|等于`"holder_binding_pseudonym"`,第 节的过程将生成如下所示的输出。 这使用了[[CFRG-Pseudonym-BBS-Signature]]的签名生成算法。请注意包含|signer_nym_entropy|和|featureOption|值, 因为这些需要传递给持有者。
如第节所述,我们使用模拟的随机数生成过程并演示了|presentationHeader|的使用。 这里使用了与中给出的相同|seed|和|presentationHeader|。
为了创建派生证明,持有者从包含基础证明的签名文档开始。 我们将用于这些测试向量的基础文档是上述中的最终示例。 第一步是运行第节的算法以恢复|bbsSignature|、|bbsHeader|、|publicKey|、|hmacKey|、 |mandatoryPointers|、|signer_nym_entropy|和|featureOption|,如下所示。
接下来,持有者使用[[CFRG-Pseudonym-BBS-Signature]]的“验证和最终化”操作来验证签名并计算|nym_secret|值。 此操作使用|holder_secret|、|prover_nym|、|signer_nym_entropy|和|secret_prover_blind|值等。
接下来,持有者需要指明他们希望向验证方披露的非强制性声明(如果有),通过指定选择性披露的JSON指针。 在此情况下,持有者披露了与中给出的相同信息。 这将生成与中显示的相同|revealDocument|。
运行会生成与中显示的相同派生组索引信息, 以及与中显示的相同调整后的强制性和选择性索引。
在中,我们基于中显示的相同|verfifier_id|计算|pseudonym|。 的最终输出如下所示。请注意包含|featureOption|和计算的|pseudonym|值。
本规范的工作得到了“重启信任网络”社区的支持,该社区由 Christopher Allen、Shannon Appelcline、Kiara Robles、Brian Weller、Betty Dhamers、Kaliya Young、Manu Sporny、Drummond Reed、Joe Andrieu、Heather Vescent、Kim Hamilton Duffy、Samantha Chase、Andrew Hughes、Erica Connell、Shigeya Suzuki 和 Zaïda Rivai 组织。由 Phil Windley、Kaliya Young、Doc Searls 和 Heidi Nobantu Saul 主持的互联网身份研讨会的参与者也通过多次工作会议支持了本规范的改进,这些会议旨在教育、讨论和改进本规范。
工作组还感谢我们的主席 Brent Zundel、前主席 Kristina Yasuda,以及 W3C 工作人员联络人 Ivan Herman,他们在 W3C 标准化过程中提供了专业管理和稳定指导。
本规范的部分工作得到了美国国土安全部科学与技术局的资助,合同号为 70RSAT20T00000003、70RSAT20T00000029、70RSAT20T00000033、70RSAT21T00000016、70RSAT23T00000005、70RSAT20T00000010/P00001、70RSAT20T00000029、70RSAT21T00000016/P00001、70RSAT23T00000005、70RSAT23C00000030、70RSAT23R00000006、70RSAT24T00000011,以及国家科学基金会的资助(NSF 22-572)。本规范的内容不一定反映美国政府的立场或政策,不应推断为官方认可。
工作组还感谢以下个人对本规范的审阅和反馈(按字母顺序排列):
Will Abramson, Mahmoud Alkhraishi, Christopher Allen, Joe Andrieu, Bohdan Andriyiv, Anthony, George Aristy, Hadley Beeman, Greg Bernstein, Bob420, Sarven Capadisli, Melvin Carvalho, David Chadwick, Matt Collier, Gabe Cohen, Sebastian Crane, Kyle Den Hartog, Veikko Eeva, Eric Elliott, Raphael Flechtner, Julien Fraichot, Benjamin Goering, Kim Hamilton Duffy, Joseph Heenan, Helge, Ivan Herman, Michael Herman, Anil John, Andrew Jones, Michael B. Jones, Rieks Joosten, Gregory K, Gregg Kellogg, Filip Kolarik, David I. Lehn, Charles E. Lehner, Christine Lemmer-Webber, Eric Lim, Dave Longley, Tobias Looker, Jer Miller, nightpool, Luis Osta, Nate Otto, George J. Padayatti, Addison Phillips, Mike Prorock, Brian Richter, Anders Rundgren, Eugeniu Rusu, Markus Sabadello, silverpill, Wesley Smith, Manu Sporny, Patrick St-Louis, Orie Steele, Henry Story, Oliver Terbu, Ted Thibodeau Jr, John Toohey, Bert Van Nuffelen, Mike Varley, Snorre Lothar von Gohren Edwin, Jeffrey Yasskin, Kristina Yasuda, Benjamin Young, Dmitri Zagidulin, and Brent Zundel.