Web Cryptography 2 级

W3C 首次公开工作草案

关于此文档的更多细节
此版本
https://w3org.cn/TR/2025/WD-webcrypto-2-20250422/
最新发布版本
https://w3org.cn/TR/webcrypto-2/
最新编辑草案
https://w3c.github.io/webcrypto/
历史
https://w3org.cn/standards/history/webcrypto-2/
提交历史
编辑
(Proton AG)
前任编辑
Mark Watson - 截至
Ryan Sleevi - 截至
反馈
GitHub w3c/webcrypto (pull requests, new issue, open issues)

摘要

本规范描述了一种用于在 Web 应用中执行基本加密操作(例如哈希、签名生成与验证、加密与解密)的 JavaScript API。此外,它还描述了应用程序用于生成和/或管理执行这些操作所需的密钥材料的 API。该 API 的用途包括用户或服务身份验证、文档或代码签名,以及通信的机密性和完整性保护。

本文档状态

本节描述了本文档发布时的状态。当前的 W3C 出版物列表及本技术报告的最新修订版可在 W3C 标准与草案索引(网址:https://w3org.cn/TR/)中找到。

本文档由 Web 应用安全工作组 发布,作为使用 推荐标准轨道 的首次公开工作草案。

作为首个公开工作草案发布并不意味着得到 W3C 及其成员的认可。

这是一份草案文档,可能会随时被其他文档更新、替换或废弃。将其作为非进行中工作引用是不恰当的。

本文档由在一个遵循 W3C 专利政策 的小组下运作。 W3C 维护了一份 与该小组交付成果相关的专利披露公开列表;该页面还包含了披露专利的说明。任何知悉其本人认为包含 必要权利要求 (Essential Claim(s)) 的专利的个人,必须按照 W3C 专利政策第 6 节 披露该信息。

本文档受 2023 年 11 月 3 日 W3C 流程文档 管辖。

1. 简介

本节是非规范性的。

Web Cryptography API 定义了一个低级接口,用于与用户代理管理或暴露的加密密钥材料进行交互。API 本身并不了解底层密钥存储的具体实现,但提供了一套通用的接口,允许功能丰富的 Web 应用执行诸如签名生成与验证、哈希与验证、加密与解密等操作,而无需访问原始密钥材料。

加密转换通过 SubtleCrypto 接口暴露,该接口定义了一套执行常见加密操作的方法。除了签名生成与验证、哈希与验证以及加密与解密等操作外,该 API 还提供了用于密钥生成、密钥派生以及密钥导入与导出的接口。

2. 用例

本节是非规范性的。

2.1 多因素身份验证

Web 应用可能希望扩展或替换现有的基于用户名/密码的身份验证方案,转而使用基于证明用户拥有某些秘密密钥材料的身份验证方法。相比于使用传输层身份验证(如 TLS 客户端证书),Web 应用可能更偏好在应用内部进行身份验证所带来的更丰富的用户体验。

利用 Web Cryptography API,应用可以定位合适的客户端密钥(这些密钥可能之前已由用户代理生成,或由 Web 应用带外预先配置)。然后,它可以执行加密操作,例如解密身份验证质询,随后签署身份验证响应。

这种交换可以通过将身份验证绑定到客户端正在进行身份验证的 TLS 会话上来进一步加强,具体做法是基于底层传输的属性派生密钥。

如果用户尚未拥有与其账户关联的密钥,Web 应用可以引导用户代理生成新密钥或重用用户选择的现有密钥。

2.2 受保护的文档交换

Web 应用可能希望限制包含敏感或个人信息的文档的查看权限,即使这些文档是通过安全渠道(如 TLS)接收的。

利用 Web Cryptography API,应用可以通过使用秘密密钥加密文档,然后用与授权查看者关联的公钥封装该密钥来实现这一目的。当用户代理导航到此类 Web 应用时,应用会发送文档的加密形式。然后,用户代理会通过使用用户的私钥解封装加密密钥,并据此解密和显示文档。

2.3 云存储

Web 应用可能希望允许用户在上传之前保护存储在远程服务提供商处的数据和文档的机密性。

利用 Web Cryptography API,应用可以让用户选择一个私钥或秘密密钥,根据所选密钥可选地派生出一个加密密钥,加密文档,然后使用现有 API 将加密数据上传到服务提供商。

此用例类似于 受保护的文档交换 用例,区别在于文档的查看范围仅限于用户本人。

2.4 文档签名

Web 应用可能希望接受文档上的电子签名,以取代对物理签名的要求。

利用 Web Cryptography API,应用可以引导用户选择一个密钥(该密钥可能是预先配置的,或是专门为该 Web 应用生成的)。使用此密钥,应用可以对某些数据执行签名操作,作为用户接受该文档的证明。

2.5 数据完整性保护

Web 应用可能希望在本地缓存数据,同时确保这些数据不会在离线攻击中被篡改。

利用 Web Cryptography API,应用可以使用应用内部包含的公钥来验证数据缓存的内容。之前,当数据被添加到缓存时,服务器会使用相应的私钥进行签名。通过在从缓存恢复数据时验证签名,客户端可以确保缓存数据未被篡改。

2.6 安全消息传递

Web 应用可能希望使用诸如离线(OTR)消息传递之类的方案来采用消息层安全性,即使这些消息已经过安全接收(例如通过 TLS)。

Web Cryptography API 通过允许执行密钥协商,实现了 OTR 及类似的消息签名方案。双方可以协商共享加密密钥和消息认证码 (MAC) 密钥,以允许对消息进行加密和解密,并防止篡改。

2.7 JavaScript 对象签名与加密 (JOSE)

Web 应用可能希望与 IETF JavaScript 对象签名和加密 (JOSE) 工作组定义的结构和消息格式进行交互。

利用 Web Cryptography API,应用可以读取和导入以 JSON 密钥格式 (JWK) 编码的密钥,验证使用数字签名或 MAC (JWS) 保护完整性的消息,或解密已加密的消息 (JWE)。

3. 一致性

除了标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文档中的关键词 MUST (必须)、REQUIRED (必需) 和 SHALL (应) 应按照 BCP 14 [RFC2119] [RFC8174] 的描述进行解释,且仅在它们以全大写形式出现时才具有此含义,如图所示。

本规范定义了以下一致性类:

符合要求的一致性用户代理

如果一个用户代理满足本规范中适用于实现的所有 MUSTREQUIREDSHALL 级别的标准,则将其视为 符合要求的一致性用户代理。本规范使用“符合要求的一致性用户代理”和“用户代理”这两个术语来指代该产品类别。

以算法或具体步骤表述的一致性要求可以以任何方式实现,只要最终结果等效即可。(特别说明,本规范中定义的算法旨在易于遵循,而非旨在达到高性能。)

使用 ECMAScript 实现本规范定义 API 的用户代理 MUST 以与 Web IDL 规范 [WebIDL] 中定义的 ECMAScript 绑定一致的方式实现它们,因为本规范使用了该规范及其术语。

除非另有说明,否则字符串比较以 区分大小写 的方式进行。本规范中用等宽字体编写的字符串字面量(例如 "this")不包括外层的引号。

3.1 可扩展性

强烈建议不要使用本规范的厂商专有扩展。作者不得使用此类扩展,因为这样做会降低互操作性并导致用户群体碎片化,仅允许特定用户代理的用户访问相关内容。

如果需要厂商专有扩展,则成员名称应添加厂商专有前缀,以防止与本规范的未来版本发生冲突。必须定义扩展,以使扩展的使用既不矛盾也不导致规范定义功能的非一致性。

当需要本规范的厂商中立扩展时,可以相应地更新本规范,或者编写一个覆盖本规范中要求的扩展规范。当应用本规范的活动方决定采纳此类扩展规范的要求时,它就成为本规范一致性要求目的下的 适用规范 (applicable specification)。由 W3C Web Cryptography 工作组定义的适用规范列于下表中。

规范 参考
建议读者查阅本规范的勘误表以获取上表的更新。

4. 范围

本节是非规范性的。

4.1 抽象级别

本规范试图关注各种平台特定或标准化加密 API 之间的通用功能和特性,并避免特定于一两个实现的特性和功能。因此,该 API 允许密钥生成、管理和交换,其抽象级别避免了开发人员需要关心底层密钥存储的实现。该 API 专门围绕 CryptoKey 对象展开,作为对底层原始加密密钥材料的抽象。其目的是允许一个足够通用的 API,使得符合要求的用户代理能够暴露由用户代理直接存储和管理的密钥,这些密钥可以通过操作系统提供的每用户密钥存储等隔离存储 API 进行存储或管理,或者存储在安全元件等密钥存储设备内,同时允许丰富的 Web 应用操作密钥,而无需 Web 应用了解底层密钥存储的性质。

4.2 加密算法

由于底层加密实现在符合要求的用户代理之间会有所不同,并可能受限于本地政策(包括但不限于政府或行业监管、安全最佳实践、知识产权问题和受限操作环境等方面的考量),本规范并不规定必须实现的强制性算法集。相反,它定义了一组可以在算法独立方式下使用的通用绑定,一个用于发现用户代理或密钥句柄是否支持底层算法的通用框架,以及在实现时针对各个算法行为的一套一致性要求。

4.3 超出范围

虽然该 API 允许应用生成、检索和操作密钥材料,但它并没有具体解决特定类型密钥存储(如安全元件或智能卡)中密钥的配置问题。这是因为此类配置操作通常带有厂商特定的细节,使得定义一个与厂商无关的接口成为一项不切实际的无界任务。此外,该 API 也不处理或解决加密模块的发现问题,因为此类概念依赖于底层的用户代理,且不是可在常见操作系统、加密库和实现之间移植的概念。

5. 概念

本节是非规范性的。

5.1 底层加密实现

本规范假设,但不要求,符合要求的用户代理不会也不将直接在用户代理本身内实现加密操作。历史上,许多用户代理将加密操作(例如 TLS 中使用的那些)延迟到作为底层操作系统一部分的现有 API 或独立于用户代理管理的第三方模块中。

CryptoKey 对象代表了 JavaScript 执行环境与这些底层库之间的桥梁,通过使用名为 [[handle]] 的内部槽位。句柄代表了一种特定于实现的非透明类型,该类型可能无法在 JavaScript 类型中表示,也不会暴露给脚本作者。通过这种方式,CryptoKey 对象对于 JavaScript 执行环境而言,在概念上等同于 [[handle]] 对于底层加密实现的作用。

这些 API 传统上围绕加密提供程序的概念构建,即对一组算法特定实现的抽象。操作系统或库可能带有默认提供程序,用户经常被允许添加其他提供程序、重新配置启用的算法集,或以其他方式自定义加密服务的提供方式。

虽然假设大多数用户代理将与纯软件实现的加密提供程序交互,但这并非本规范的要求。因此,某些实现的功能可能会受到底层硬件功能的限制,并且根据用户配置底层加密库的方式,这对用户代理来说可能是完全不透明的。

5.2 密钥存储

本规范并未显式为 CryptoKey 对象提供任何新的存储机制。相反,通过为 CryptoKey 对象定义 序列化和反序列化步骤,任何支持存储 可序列化对象 的现有或未来 Web 存储机制均可用于存储 CryptoKey 对象。

实际上,预计大多数作者将利用 Indexed Database API [INDEXEDDB],它允许键/值对的关联存储,其中键是对于应用有意义的某个字符串标识符,值则是 CryptoKey 对象。这允许在不向应用或 JavaScript 环境暴露密钥材料的情况下存储和检索密钥材料。此外,这允许作者完全灵活地随 CryptoKey 本身存储任何附加元数据。

6. 安全考量

本节是非规范性的。

6.1 实现者的安全考量

由于不提供明确的存储机制,本规范假设 CryptoKey 对象的作用域仅限于当前的执行环境以及该环境可用的任何存储机制(例如 Indexed Database API)。应用作者依赖此机制来保证其应用的安全性;两个拥有相同 CryptoKey 对象的源对底层密钥拥有完全访问权限,因此,来自这些应用的消息无法区分,并且发送给这些应用的消息可以被完全恢复。实现者应确保除非作者明确选择共享(例如通过使用 postMessage),否则不会在两个源之间共享 CryptoKey 对象。

本规范中指定的许多算法执行计算密集型工作,例如生成极大的素数,或通过特定操作的重复迭代。因此,敌对应用可能会试图滥用此 API 并尝试导致实现执行大量工作,从而拒绝向正在执行的其他应用提供访问或服务。实现应采取措施减轻这些风险,例如限制实现并发执行的操作数量,要求用户对已知会破坏执行环境的操作给予许可,或定义针对设备属性(如密钥大小或迭代次数)的限制。

6.2 作者的安全考量

本规范包含了各种加密操作的描述,其中一些在不当使用时存在已知弱点。应用开发人员必须小心谨慎,审阅适当且最新的加密文献,以理解并减轻此类问题。通常情况下,强烈建议应用开发人员不要发明新的加密协议;与所有应用一样,使用本规范的开发者应通过使用现有协议来获得最佳服务,本规范提供了实现这些协议所需的必要构建块。

为了使用本规范定义的 API 提供任何有意义的加密保障,作者必须熟悉 Web 应用现有的威胁,以及所采用的底层安全模型。从概念上讲,脚本注入等问题等同于其他操作环境中的远程代码执行,允许注入敌对脚本可能会导致密钥或数据的泄露。脚本注入可能来自其他应用,这可以通过合理使用内容安全策略 (Content Security Policy) 来减轻;或者可能来自敌对的网络中介,这可以通过使用传输层安全性 (Transport Layer Security) 来减轻。

本规范未定义任何用于存储加密密钥的具体机制。默认情况下,除非作者通过使用 Indexed Database API 等方式专门努力持久化密钥,否则使用此 API 创建的密钥仅在当前页面期间有效(例如直到导航事件发生)。希望在不同页面或多个浏览会话中使用同一密钥的作者必须使用现有的 Web 存储技术。作者应意识到这些技术的安全假设,例如同源安全模型;即任何共享相同协议、主机和端口的应用都可以访问相同的存储分区,即使路径等其他信息可能有所不同。作者可以通过使用跨源共享(如 postMessage)明确选择放宽此安全限制。

作者应意识到,本规范对于实现如何存储底层加密密钥材料没有强制性要求。唯一的要求是,除非使用 exportKeywrapKey 操作,否则密钥材料不会暴露给脚本。特别地,它不保证底层加密密钥材料不会被持久化到磁盘(可能是未加密的),也不保证它不会被与用户代理具有相同权限的用户或其他应用所访问。任何有权访问设备存储的应用或用户可能能够恢复密钥材料,即使脚本可能被禁止这样做。

本规范对于实现如何在所有对其引用消失后处理密钥材料没有强制性要求。也就是说,符合要求的用户代理不需要对密钥材料进行零化处理,即使在所有对 CryptoKey 的引用消失后,它仍可能在设备存储或设备内存中被访问。

应用可以通过使用结构化克隆算法和诸如 postMessage 之类的 API,跨安全边界(如源)共享 CryptoKey 对象。虽然基于 extractable 属性,对底层加密密钥材料的访问可能受到限制,但一旦密钥与目标源共享,源端便无法在以后限制或撤销对该密钥的访问。因此,作者必须确保信任目标源能够采取与源端相同的针对敌对脚本的防御措施。此外,如果源端发生脚本注入,攻击者可能会将密钥发布到受攻击者控制的源。只要用户代理访问攻击者的源,用户代理就可能被引导使用该密钥执行加密操作,例如解密现有消息或创建新的欺诈消息。

作者应意识到用户可能随时选择清除与某源关联的存储,从而可能销毁密钥。旨在提供长期存储(如在服务器上)的应用应考虑采用密钥托管 (key escrow) 等技术,以防止此类数据无法访问。作者不应假设密钥将无限期可用。

6.3 用户的安全考量

使用本规范定义 API 的应用的用户应意识到,无论采用何种加密技术,这些应用都将拥有对所有交换消息的完全访问权限。也就是说,对于加密的消息,使用这些 API 的应用也将拥有对解密后消息的完全访问权限。

7. 隐私考量

本节是非规范性的。

指纹识别
通过暴露反映底层平台功能的附加 API,本规范可能允许恶意应用确定或区分不同的用户代理或设备。
超级 Cookie
本规范并未提供任何手段让恶意应用创建寿命长于现有 Web 存储技术的标识符。然而,在引入对此 API 的未来修订或额外加密功能(例如基于硬件的功能,如智能卡或可信平台模块)时必须小心。考虑到此类存储旨在防止任何两个用户拥有相同的底层密钥数据,此类 API 可能代表了被恶意用作违背用户意愿的永久标识符的真正风险。
使用 randomUUID 作为用户 ID
randomUUID 对于生成 用户 ID 非常有用,但不能直接提供生成 全局标识符 的任何能力。

8. 依赖项

本规范依赖于底层规范。

DOM

一个 符合要求的一致性用户代理 MUST 支持至少本规范所依赖的 DOM 功能子集;特别地,它 MUST 支持 PromiseDOMException。[DOM]

HTML

一个 符合要求的一致性用户代理 MUST 支持至少本规范所依赖的 HTML 功能子集;特别地,它 MUST 支持 ArrayBufferView typedef 和 可序列化对象。[HTML]

Web IDL

一个 符合要求的一致性用户代理 MUST 是本规范中 IDL 片段的符合要求的实现,如 Web IDL 规范中所述。[WebIDL]

9. 术语

术语 ArrayBufferArrayBufferView可序列化对象 (serializable objects) 由 HTML 规范定义 [HTML]。

术语 DOMStringBufferSource 定义在 [WEBIDL] 中。

术语 字节序列 (byte sequence) 定义在 [Infra] 中。

字节序列位长 (length in bits) 是其 长度 乘以 8。

包含位序列的字节序列 b 是通过首先向 b 追加零个或多个零位,使得生成的位序列长度最小且为 8 的整数倍,然后将该字符串中的每个连续 8 位序列视为一个字节而获得的 字节序列

当本规范说要 将非负整数 i 转换为长度为 n 的字节序列(其中 n * 8 大于 i 的以 2 为底的对数)时,用户代理必须首先计算 i 的二进制表示(最高有效位优先),在其前面加上足够的零位以形成长度为 n * 8 的位序列,然后返回通过将该位序列中的每个连续 8 位视为一个字节所形成的 字节序列

区分大小写 (case-sensitive) 的方式比较两个字符串意味着逐个码点地完全精确比较它们。

ASCII 不区分大小写 (ASCII case-insensitive) 的方式比较两个字符串意味着逐个码点地完全精确比较它们,区别在于范围 U+0041 .. U+005A(即大写字母 A 到 Z)内的码点与范围 U+0061 .. U+007A(即小写字母 a 到 z)内相应的码点也被视为匹配。

当本规范说要 终止算法 时,用户代理必须在完成当前步骤后终止该算法。所指的算法是规范定义的处理步骤集,而不是可能正在处理中的底层加密算法。

当本规范说要 解析 ASN.1 结构 时,用户代理必须执行以下步骤:

  1. data 为要解析的字节序列。

  2. structure 为要解析的 ASN.1 结构。

  3. exactData 为可选的布尔值。如果未提供,则将其初始化为 true

  4. 根据 [X690] 的区分编码规则 (DER) 解析 data,使用 structure 作为要解码的 ASN.1 结构。

  5. 如果指定了 exactData,且在解析阶段未消耗完 data 的所有字节,则 抛出 一个 DataError

  6. 返回解析后的 ASN.1 结构。

当本规范说要 解析 subjectPublicKeyInfo 时,用户代理必须 解析 ASN.1 结构,其中 data 设置为要解析的字节序列,structure 设置为 [RFC5280] 中指定的 subjectPublicKeyInfo 的 ASN.1 结构,并且 exactData 设置为 true

当本规范说要 解析 PrivateKeyInfo 时,用户代理必须 解析 ASN.1 结构,其中 data 设置为要解析的字节序列,structure 设置为 [RFC5208] 中指定的 PrivateKeyInfo 的 ASN.1 结构,并且 exactData 设置为 true

当本规范说要 解析 JWK 时,用户代理必须运行以下步骤:

  1. data 为要解析的字节序列。

  2. json 为根据 UTF-8 解码 data 后得到的 Unicode 字符串。

  3. json 转换为 UTF-16。

  4. result 为在新的全局对象上下文中执行 JSON.parse 内部函数后得到的对象字面量,其中 text 参数设置为包含 json 的 JavaScript 字符串。

  5. key 为将 result 转换为 JsonWebKey 的 IDL 字典类型的结果。

  6. 如果 keykty 字段未定义,则 抛出 一个 DataError

  7. 返回 key

当本规范说要计算两个序列 ab使用交集 (usage intersection) 时,结果应为一个序列,包含同时出现在 ab 中的每个 已识别的密钥用法值,顺序按照 已识别的密钥用法值 列表中的顺序排列,其中若序列中存在与该值区分大小写匹配的元素,则称该值出现在序列中。

当本规范说要计算 用法列表的规范化值 (normalized value of a usages list) usages 时,结果应为 usages 与包含所有 已识别的密钥用法值 的序列之间的 使用交集

当本规范提及与 object 的内部槽位 [[slot]] 关联的 缓存的 ECMAScript 对象 (cached ECMAScript object) 时,用户代理必须运行以下步骤:

  1. 如果 object 的 [[slot_cached]] 内部槽位未定义:
    object 的 [[slot_cached]] 内部槽位设置为对 object 的 [[slot]] 内部槽位的内容执行 [WebIDL] 中定义的 ECMAScript 对象类型转换后的结果。
  2. 返回 object 的 [[slot_cached]] 内部槽位的内容。

10. Crypto 接口

Crypto 接口代表了通用加密功能的接口,包括使用真正随机值作为种子的密码学强伪随机数生成器。

WebIDLpartial interface mixin WindowOrWorkerGlobalScope {
  [SameObject] readonly attribute Crypto crypto;
};

[Exposed=(Window,Worker)]
interface Crypto {
  [SecureContext] readonly attribute SubtleCrypto subtle;
  ArrayBufferView getRandomValues(ArrayBufferView array);
  [SecureContext] DOMString randomUUID();
};
实现应使用以高质量熵(例如来自操作系统熵源,如 "/dev/urandom")为种子的成熟加密伪随机数生成器来生成密码学强随机值。本规范对密码学强随机值中存在的理论信息熵没有下限要求,但实现应尽最大努力提供尽可能多的熵。
此接口定义了一个用于获取密码学强随机值的同步方法。虽然某些设备和实现可能支持真正的随机加密数生成器,或在熵不足时提供阻塞接口,但不建议在实现 getRandomValues 时使用这些源,既是为了性能,也是为了避免耗尽系统的熵。相反,这些源应被用于为加密伪随机数生成器播种,该生成器随后可以高效地返回合适的值。

10.1 方法与参数

10.1.1 getRandomValues 方法

getRandomValues 方法生成密码学强随机值。它必须按如下方式执行:

  1. 如果 array 不是 Int8ArrayUint8ArrayUint8ClampedArrayInt16ArrayUint16ArrayInt32ArrayUint32ArrayBigInt64ArrayBigUint64Array,则 抛出 一个 TypeMismatchError终止算法

  2. byteLengtharray字节长度

  3. 如果 byteLength 大于 65536,则 抛出 一个 QuotaExceededError终止算法

  4. bytes 为长度为 byteLength字节序列

  5. 用密码学安全的随机字节填充 bytes

  6. bytes 写入 array

  7. 返回 array

不要使用 getRandomValues 方法生成密钥。请改用 generateKey 方法。

10.1.2 randomUUID 方法

randomUUID 方法生成一个新的 4 版本 UUID 并返回其 命名空间特定字符串表示形式,如 [RFC4122] 的 第 3 节 所述。若要 生成随机 UUID

  1. bytes 为长度为 16 的 字节序列
  2. 用密码学安全的随机字节填充 bytes
  3. bytes[6] 的 4 个最高有效位(代表 UUID 版本)设置为 0100
  4. bytes[8] 的 2 个最高有效位(代表 UUID 变体)设置为 10
  5. 返回以下各项的 字符串拼接

    1. bytes[0] 的 十六进制表示, bytes[1] 的 十六进制表示, bytes[2] 的 十六进制表示, bytes[3] 的 十六进制表示,
    2. "-",
    3. bytes[4] 的 十六进制表示, bytes[5] 的 十六进制表示,
    4. "-",
    5. bytes[6] 的 十六进制表示, bytes[7] 的 十六进制表示,
    6. "-",
    7. bytes[8] 的 十六进制表示, bytes[9] 的 十六进制表示,
    8. "-",
    9. bytes[10] 的 十六进制表示, bytes[11] 的 十六进制表示, bytes[12] 的 十六进制表示, bytes[13] 的 十六进制表示, bytes[14] 的 十六进制表示, bytes[15] 的 十六进制表示

    »。

对于算法中描述的 生成随机 UUID 的步骤,字节 value十六进制表示 (hexadecimal representation) 是通过使用 ASCII 小写十六进制数字 以十六进制表示 value 创建的双字符字符串,左侧补 "0" 以达到两个 ASCII 小写十六进制数字

10.2 属性

10.2.1 subtle 属性

subtle 属性提供 SubtleCrypto 接口的一个实例,该接口提供低级加密原语和算法。

11. Algorithm 字典

Algorithm 对象是一个字典对象 [WEBIDL],用于指定算法以及完全指定所需操作所需的任何附加参数。

WebIDLtypedef (object or DOMString) AlgorithmIdentifier;

typedef AlgorithmIdentifier HashAlgorithmIdentifier;

dictionary Algorithm {
  required DOMString name;
};

11.1 Algorithm 字典成员

name
要使用的 已注册算法 的名称。

12. KeyAlgorithm 字典

KeyAlgorithm 字典表示有关给定 CryptoKey 对象内容的信息。

WebIDLdictionary KeyAlgorithm {
  required DOMString name;
};

12.1 描述

本节是非规范性的。

KeyAlgorithm 字典旨在帮助记录 CryptoKey 的固定、公共属性如何反映回应用。实际的字典类型永远不会暴露给应用。

12.2 KeyAlgorithm 字典成员

name
用于生成 CryptoKey 的算法名称。

13. CryptoKey 接口

CryptoKey 对象代表对由用户代理管理的密钥材料的不透明引用。

WebIDLenum KeyType { "public", "private", "secret" };

enum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" };

[SecureContext,Exposed=(Window,Worker),Serializable]
interface CryptoKey {
  readonly attribute KeyType type;
  readonly attribute boolean extractable;
  readonly attribute object algorithm;
  readonly attribute object usages;
};

13.1 描述

本节是非规范性的。

本规范为用户代理管理的许多不同种类的密钥材料提供了一个统一的接口。这可能包括:由用户代理生成的密钥;由用户代理从其他密钥派生的密钥;通过用户操作或使用此 API 导入到用户代理的密钥;在用户代理有权访问的软件或硬件中预先配置的密钥;或以其他方式提供给用户代理的密钥。术语“密钥”广义上指任何密钥材料,包括加密操作的实际密钥,以及在密钥派生或交换操作中获得的秘密值。

CryptoKey 对象不需要直接与底层密钥存储机制接口,而可能只是用户代理在需要时(例如执行加密操作时)了解如何获取密钥材料的引用。

13.2 Key 接口数据类型

KeyType
密钥的类型。已识别的密钥类型值 是 "public"、"private" 和 "secret"。不透明密钥材料(包括用于对称算法的材料)由 secret 表示,而作为由公钥/私钥对组成的非对称算法一部分使用的密钥将是 publicprivate
KeyUsage
可以使用密钥执行的操作类型。已识别的密钥用法值 包括 encryptdecryptsignverifyderiveKeyderiveBitswrapKeyunwrapKey

13.3 CryptoKey 内部槽位

每个 CryptoKey 对象都有一组内部槽位,用于存储有关密钥的信息。这些槽位不作为本规范的一部分暴露;它们代表实现用来执行本规范的内部状态。这里重用了 [ECMA-262] 中使用的符号约定;内部槽位由括在双方括号 [[ ]] 中的名称标识。

所有 CryptoKey 对象都具有名为 [[type]][[extractable]][[algorithm]][[algorithm_cached]][[usages]][[usages_cached]][[handle]] 的内部槽位。

[[algorithm]] 内部槽位的内容应当是或派生自 KeyAlgorithm[[usages]] 内部槽位的内容应当是 Sequence<KeyUsage> 类型。

[[handle]] 槽位是一种不透明类型,其中包含底层加密实现用于表示逻辑密钥的任何数据。不同的加密实现可能使用不同的类型,范围从表示为整数的不透明标识符、指针类型,到提供标识信息的结构体。这些句柄永远不会暴露给应用程序。

13.4 CryptoKey 接口成员

type
反映 [[type]] 内部槽位,该槽位包含底层密钥的类型。
extractable
反映 [[extractable]] 内部槽位,该槽位指示应用程序是否可以导出原始密钥材料。
algorithm
返回与 [[algorithm]] 内部槽位相关联的 缓存的 ECMAScript 对象
usages
返回与 [[usages]] 内部槽位相关联的 缓存的 ECMAScript 对象,该对象指示哪些加密操作允许与此密钥一起使用。

13.5 序列化与反序列化步骤

CryptoKey 对象是 可序列化对象。给定 valueserialized,其 序列化步骤 为:

  1. serialized.[[Type]] 设置为 value[[type]] 内部槽位。
  2. serialized.[[Extractable]] 设置为 value[[extractable]] 内部槽位。
  3. serialized.[[Algorithm]] 设置为 value[[algorithm]] 内部槽位的 子序列化结果。
  4. serialized.[[Usages]] 设置为 value[[usages]] 内部槽位的 子序列化结果。
  5. serialized.[[Handle]] 设置为 value[[handle]] 内部槽位。

给定 serializedvalue,其 反序列化步骤 为:

  1. value[[type]] 内部槽位初始化为 serialized.[[Type]]。
  2. value[[extractable]] 内部槽位初始化为 serialized.[[Extractable]]。
  3. value[[algorithm]] 内部槽位初始化为 serialized.[[Algorithm]] 的 子反序列化结果。
  4. value[[usages]] 内部槽位初始化为 serialized.[[Usages]] 的 子反序列化结果。
  5. value[[handle]] 内部槽位初始化为 serialized.[[Handle]]。
在反序列化序列化的 CryptoKey 对象时,重要的是该对象不得被反序列化为不同类型。这在 反序列化步骤 的定义中是规范要求的,但值得特别注意,因为此类反序列化可能会暴露密钥材料的内容,在某些情况下(例如当 [[extractable]] 内部槽位为 false 时),这些内容不应暴露给应用程序。

14. SubtleCrypto 接口

SubtleCrypto 接口提供了一组用于处理底层加密原语和算法的方法。

WebIDLenum KeyFormat { "raw", "spki", "pkcs8", "jwk" };

[SecureContext,Exposed=(Window,Worker)]
interface SubtleCrypto {
  Promise<ArrayBuffer> encrypt(
    AlgorithmIdentifier algorithm,
    CryptoKey key,
    BufferSource data
  );
  Promise<ArrayBuffer> decrypt(
    AlgorithmIdentifier algorithm,
    CryptoKey key,
    BufferSource data
  );
  Promise<ArrayBuffer> sign(
    AlgorithmIdentifier algorithm,
    CryptoKey key,
    BufferSource data
  );
  Promise<boolean> verify(
    AlgorithmIdentifier algorithm,
    CryptoKey key,
    BufferSource signature,
    BufferSource data
  );
  Promise<ArrayBuffer> digest(
    AlgorithmIdentifier algorithm,
    BufferSource data
  );

  Promise<(CryptoKey or CryptoKeyPair)> generateKey(
    AlgorithmIdentifier algorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<CryptoKey> deriveKey(
    AlgorithmIdentifier algorithm,
    CryptoKey baseKey,
    AlgorithmIdentifier derivedKeyType,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<ArrayBuffer> deriveBits(
    AlgorithmIdentifier algorithm,
    CryptoKey baseKey,
    optional unsigned long? length = null
  );

  Promise<CryptoKey> importKey(
    KeyFormat format,
    (BufferSource or JsonWebKey) keyData,
    AlgorithmIdentifier algorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<(ArrayBuffer or JsonWebKey)> exportKey(
    KeyFormat format,
    CryptoKey key
  );

  Promise<ArrayBuffer> wrapKey(
    KeyFormat format,
    CryptoKey key,
    CryptoKey wrappingKey,
    AlgorithmIdentifier wrapAlgorithm
  );
  Promise<CryptoKey> unwrapKey(
    KeyFormat format,
    BufferSource wrappedKey,
    CryptoKey unwrappingKey,
    AlgorithmIdentifier unwrapAlgorithm,
    AlgorithmIdentifier unwrappedKeyAlgorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
};

SubtleCrypto 接口被命名为“SubtleCrypto”,以反映这样一个事实:为了提供所需的算法安全保证,许多这些算法都有微妙的使用要求。

例如,直接使用未经身份验证的加密方案(例如 AES 计数器模式)会使潜在攻击者能够通过操纵输入中的位来操纵输出中的位,从而破坏消息的完整性。然而,AES-CTR 可以与其他加密原语(例如消息认证码)结合使用以确保受保护消息的完整性,但这仅在针对加密消息和 IV 构建消息认证码时才有效。

使用 SubtleCrypto 接口的开发人员应了解与所提供的各种算法的设计和实现相关的安全问题。提供原始算法是为了让开发人员能够在实现各种协议和应用程序时获得最大的灵活性,其中每一个都可能以独特的方式表示组合和安全参数,从而需要使用原始算法。

14.1 数据类型

KeyFormat
指定密钥的序列化格式。认可的密钥格式值 为:
raw
未格式化的字节序列。旨在用于秘密密钥。
pkcs8
[RFC5208] 中 PrivateKeyInfo 结构的 DER 编码。
spki
[RFC5280] 中 SubjectPublicKeyInfo 结构的 DER 编码。
jwk
密钥是编码为 JavaScript 对象的 JsonWebKey 字典。

14.2 任务源

加密任务源
任务源 用于将任务排队,以解析或拒绝响应调用 SubtleCrypto 方法而创建的 Promise。
本规范对响应调用 SubtleCrypto 方法的顺序没有具体要求,无论是多次调用之间,还是调用与来自其他 任务源 的任务之间。此任务源仅用于在加密操作完成时 排队一个任务 以解析或拒绝相关的 Promise,以 防止竞争条件

14.3 方法与参数

所有错误均通过拒绝返回的 Promise 异步报告。这包括 Web IDL 类型映射错误。

14.3.1 encrypt 方法

encrypt 方法返回一个新的 Promise 对象,该对象将使用指定的 AlgorithmIdentifier 和提供的 CryptoKey 来加密数据。它必须执行如下操作:

  1. algorithmkey 分别为传递给 encrypt() 方法的 algorithmkey 参数。

  2. data获取传递给 encrypt() 方法的 data 参数所持有的字节副本 的结果。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "encrypt"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. 如果 normalizedAlgorithmname 成员不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  10. 如果 key[[usages]] 内部槽位不包含 "encrypt" 条目,则 抛出 InvalidAccessError

  11. ciphertext 为执行由 normalizedAlgorithm 指定的加密操作的结果,使用 algorithmkey,并以 data 作为 plaintext

  12. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  13. result 为在 realm创建 包含 ciphertextArrayBuffer 的结果。

  14. result 解析 promise

14.3.2 decrypt 方法

decrypt 方法返回一个新的 Promise 对象,该对象将使用指定的 AlgorithmIdentifier 和提供的 CryptoKey 来解密数据。它必须执行如下操作:

  1. algorithmkey 分别为传递给 decrypt() 方法的 algorithmkey 参数。

  2. data获取传递给 decrypt() 方法的 data 参数所持有的字节副本 的结果。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "decrypt"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. 如果 normalizedAlgorithmname 成员不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  10. 如果 key[[usages]] 内部槽位不包含 "decrypt" 条目,则 抛出 InvalidAccessError

  11. plaintext 为执行由 normalizedAlgorithm 指定的解密操作的结果,使用 keyalgorithm,并以 data 作为 ciphertext

  12. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  13. result 为在 realm创建 包含 plaintextArrayBuffer 的结果。

  14. result 解析 promise

14.3.3 sign 方法

sign 方法返回一个新的 Promise 对象,该对象将使用指定的 AlgorithmIdentifier 和提供的 CryptoKey 来签名数据。它必须执行如下操作:

  1. algorithmkey 分别为传递给 sign() 方法的 algorithmkey 参数。

  2. data获取传递给 sign() 方法的 data 参数所持有的字节副本 的结果。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "sign"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. 如果 normalizedAlgorithmname 成员不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  10. 如果 key[[usages]] 内部槽位不包含 "sign" 条目,则 抛出 InvalidAccessError

  11. signature 为执行由 normalizedAlgorithm 指定的签名操作的结果,使用 keyalgorithm,并以 data 作为 message

  12. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  13. result 为在 realm创建 包含 signatureArrayBuffer 的结果。

  14. result 解析 promise

14.3.4 verify 方法

verify 方法返回一个新的 Promise 对象,该对象将使用指定的 AlgorithmIdentifier 和提供的 CryptoKey 来验证数据。它必须执行如下操作:

  1. algorithmkey 分别为传递给 verify() 方法的 algorithmkey 参数。

  2. signature获取传递给 verify() 方法的 signature 参数所持有的字节副本 的结果。

  3. data获取传递给 verify() 方法的 data 参数所持有的字节副本 的结果。

  4. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "verify"。

  5. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  6. realmthis相关领域

  7. promise 为一个新的 Promise。

  8. 返回 promise并行 执行剩余步骤。

  9. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  10. 如果 normalizedAlgorithmname 成员不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  11. 如果 key[[usages]] 内部槽位不包含 "verify" 条目,则 抛出 InvalidAccessError

  12. result 为执行由 normalizedAlgorithm 指定的验证操作的结果,使用 keyalgorithmsignature,并以 data 作为 message

  13. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  14. result 解析 promise

14.3.5 digest 方法

digest 方法返回一个新的 Promise 对象,该对象将使用指定的 AlgorithmIdentifier 来摘要数据。它必须执行如下操作:

  1. algorithm 为传递给 digest() 方法的 algorithm 参数。

  2. data获取传递给 digest() 方法的 data 参数所持有的字节副本 的结果。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "digest"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. digest 为执行由 normalizedAlgorithm 指定的摘要操作的结果,使用 algorithm,并以 data 作为 message

  10. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  11. result 为在 realm创建 包含 digestArrayBuffer 的结果。

  12. result 解析 promise

14.3.6 generateKey 方法

当被调用时,generateKey 必须 执行以下步骤:

  1. algorithmextractableusages 分别为传递给 generateKey() 方法的 algorithmextractablekeyUsages 参数。

  2. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "generateKey"。

  3. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  4. realmthis相关领域

  5. promise 为一个新的 Promise。

  6. 返回 promise并行 执行剩余步骤。

  7. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  8. result 为执行由 normalizedAlgorithm 指定的生成密钥操作的结果,使用 algorithmextractableusages

  9. 如果 result 是一个 CryptoKey 对象:

    如果 result[[type]] 内部槽位为 "secret" 或 "private",且 usages 为空,则 抛出 SyntaxError

    如果 result 是一个 CryptoKeyPair 对象:

    如果 resultprivateKey 属性的 [[usages]] 内部槽位为空序列,则 抛出 SyntaxError

  10. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  11. result 为根据 [WebIDL] 的定义,将 result 转换为 realm 中的 ECMAScript 对象的结果。

  12. result 解析 promise

14.3.7 deriveKey 方法

当被调用时,deriveKey 必须 执行以下步骤:

  1. algorithmbaseKeyderivedKeyTypeextractableusages 分别为传递给 deriveKey() 方法的 algorithmbaseKeyderivedKeyTypeextractablekeyUsages 参数。

  2. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "deriveBits"。

  3. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  4. normalizedDerivedKeyAlgorithmImport规范化算法 的结果,其中 alg 设置为 derivedKeyTypeop 设置为 "importKey"。

  5. 如果发生错误,则返回一个被 normalizedDerivedKeyAlgorithmImport 拒绝的 Promise。

  6. normalizedDerivedKeyAlgorithmLength规范化算法 的结果,其中 alg 设置为 derivedKeyTypeop 设置为 "get key length"。

  7. 如果发生错误,则返回一个被 normalizedDerivedKeyAlgorithmLength 拒绝的 Promise。

  8. realmthis相关领域

  9. promise 为一个新的 Promise。

  10. 返回 promise并行 执行剩余步骤。

  11. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  12. 如果 normalizedAlgorithmname 成员不等于 baseKey[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  13. 如果 baseKey[[usages]] 内部槽位不包含 "deriveKey" 条目,则 抛出 InvalidAccessError

  14. length 为执行由 normalizedDerivedKeyAlgorithmLength 指定的获取密钥长度算法的结果,使用 derivedKeyType

  15. secret 为执行由 normalizedAlgorithm 指定的导出位操作的结果,使用 keyalgorithmlength

  16. result 为执行由 normalizedDerivedKeyAlgorithmImport 指定的导入密钥操作的结果,使用 "raw" 作为 formatsecret 作为 keyDataderivedKeyType 作为 algorithm,并使用 extractableusages

  17. 如果 result[[type]] 内部槽位为 "secret" 或 "private",且 usages 为空,则 抛出 SyntaxError

  18. result[[extractable]] 内部槽位设置为 extractable

  19. result[[usages]] 内部槽位设置为 usages规范化值

  20. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  21. result 为根据 [WebIDL] 的定义,将 result 转换为 realm 中的 ECMAScript 对象的结果。

  22. result 解析 promise

14.3.8 deriveBits 方法

当被调用时,deriveBits 必须 执行以下步骤:

  1. algorithmbaseKeylength 分别为传递给 deriveBits() 方法的 algorithmbaseKeylength 参数。

  2. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "deriveBits"。

  3. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  4. realmthis相关领域

  5. promise 为一个新的 Promise。

  6. 返回 promise并行 执行剩余步骤。

  7. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  8. 如果 normalizedAlgorithmname 成员不等于 baseKey[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  9. 如果 baseKey[[usages]] 内部槽位不包含 "deriveBits" 条目,则 抛出 InvalidAccessError

  10. bits 为执行由 normalizedAlgorithm 指定的导出位操作的结果,使用 baseKeyalgorithmlength

  11. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  12. result 为在 realm创建 包含 bitsArrayBuffer 的结果。

  13. result 解析 promise

14.3.9 importKey 方法

当被调用时,importKey 方法 必须 执行以下步骤:

  1. formatalgorithmextractableusages 分别为传递给 importKey() 方法的 formatalgorithmextractablekeyUsages 参数。

  2. 如果 format 等于字符串 "raw"、"pkcs8" 或 "spki":
    1. 如果传递给 importKey() 方法的 keyData 参数是一个 JsonWebKey 字典,则 抛出 TypeError

    2. keyData获取传递给 importKey() 方法的 keyData 参数所持有的字节副本 的结果。

    如果 format 等于字符串 "jwk":
    1. 如果传递给 importKey() 方法的 keyData 参数不是 JsonWebKey 字典,则 抛出 TypeError

    2. keyData 为传递给 importKey() 方法的 keyData 参数。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "importKey"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. result 为执行由 normalizedAlgorithm 指定的导入密钥操作所产生的 CryptoKey 对象,使用 keyDataalgorithmformatextractableusages

  10. 如果 result[[type]] 内部槽位为 "secret" 或 "private",且 usages 为空,则 抛出 SyntaxError

  11. result[[extractable]] 内部槽位设置为 extractable

  12. result[[usages]] 内部槽位设置为 usages规范化值

  13. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  14. result 为根据 [WebIDL] 的定义,将 result 转换为 realm 中的 ECMAScript 对象的结果。

  15. result 解析 promise

鼓励支持 "raw" 密钥格式以实现互操作性。Web 开发人员应查阅测试套件,获取有关实现对其他密钥格式支持的详细信息。

对于结构化密钥格式 "spki"、"pkcs8" 和 "jwk",算法的密钥导入过程中未明确引用的字段将被忽略。

14.3.10 exportKey 方法

当被调用时,exportKey 方法 必须 执行以下步骤:

  1. formatkey 分别为传递给 exportKey() 方法的 formatkey 参数。

  2. realmthis相关领域

  3. promise 为一个新的 Promise。

  4. 返回 promise并行 执行剩余步骤。

  5. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  6. 如果 key[[algorithm]] 内部槽位的 name 成员无法标识支持导出密钥操作的 注册算法,则 抛出 NotSupportedError

  7. 如果 key[[extractable]] 内部槽位为 false,则 抛出 InvalidAccessError

  8. result 为执行由 key[[algorithm]] 内部槽位指定的导出密钥操作的结果,使用 keyformat

  9. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  10. 如果 format 等于字符串 "raw"、"pkcs8" 或 "spki":
    result 为在 realm创建 包含 resultArrayBuffer 的结果。
    如果 format 等于字符串 "jwk":
    result 为根据 [WebIDL] 的定义,将 result 转换为 realm 中的 ECMAScript 对象的结果。
  11. result 解析 promise

鼓励支持 "raw" 密钥格式以实现互操作性。Web 开发人员应查阅测试套件,获取有关实现对其他密钥格式支持的详细信息。

14.3.11 wrapKey 方法

当被调用时,wrapKey 方法 必须 执行以下步骤:

  1. formatkeywrappingKeyalgorithm 分别为传递给 wrapKey() 方法的 formatkeywrappingKeywrapAlgorithm 参数。

  2. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "wrapKey"。

  3. 如果发生错误,令 normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "encrypt"。

  4. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  5. realmthis相关领域

  6. promise 为一个新的 Promise。

  7. 返回 promise并行 执行剩余步骤。

  8. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  9. 如果 normalizedAlgorithmname 成员不等于 wrappingKey[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  10. 如果 wrappingKey[[usages]] 内部槽位不包含 "wrapKey" 条目,则 抛出 InvalidAccessError

  11. 如果 key[[algorithm]] 内部槽位标识的算法不支持导出密钥操作,则 抛出 NotSupportedError

  12. 如果 key[[extractable]] 内部槽位为 false,则 抛出 InvalidAccessError

    因为 wrapKey 方法实际上导出了密钥,所以只有标记为可导出的密钥才能被包装。特别是,这意味着此 API 不能创建使用 ext JWK 成员标记为不可导出的已包装 JWK 密钥。

    然而,unwrapKey 方法 *确实* 支持 ext JWK 成员,因此在其他地方(例如由服务器)创建的已包装的不可导出密钥可以使用此 API 解包。

  13. exportedKey 为执行由 key[[algorithm]] 内部槽位指定的导出密钥操作的结果,使用 keyformat

  14. 如果 format 等于字符串 "raw"、"pkcs8" 或 "spki":
    bytesexportedKey
    如果 format 等于字符串 "jwk":
    1. json 为将 exportedKey 表示为符合 JSON 语法的 UTF-16 字符串的结果;例如,通过在新全局对象的上下文中执行 [ECMA-262] 中指定的 JSON.stringify 算法。

    2. bytesUTF-8 编码 json 的结果。

    某些算法的密钥包装操作对负载大小有限制。例如,AES-KW 要求负载长度为 8 字节的倍数,而 RSA-OAEP 对长度有限制。对于在给定密钥的序列化方面提供灵活性的密钥格式(例如 JWK),实现可以选择调整序列化以适应包装算法的约束。这就是为什么不规范要求 JSON.stringify 的原因,否则它将禁止实现引入额外的填充。

  15. 如果 normalizedAlgorithm 支持包装密钥操作:

    result 为执行由 normalizedAlgorithm 指定的包装密钥操作的结果,使用 algorithmwrappingKey 作为 keybytes 作为 plaintext

    否则,如果 normalizedAlgorithm 支持加密操作:

    result 为执行由 normalizedAlgorithm 指定的加密操作的结果,使用 algorithmwrappingKey 作为 keybytes 作为 plaintext

    否则
    抛出 NotSupportedError
  16. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  17. result 为在 realm创建 包含 resultArrayBuffer 的结果。

  18. result 解析 promise

鼓励支持 "raw" 密钥格式以实现互操作性。Web 开发人员应查阅测试套件,获取有关实现对其他密钥格式支持的详细信息。

14.3.12 unwrapKey 方法

当被调用时,unwrapKey 方法 必须 执行以下步骤:

  1. formatunwrappingKeyalgorithmunwrappedKeyAlgorithmextractableusages 分别为传递给 unwrapKey() 方法的 formatunwrappingKeyunwrapAlgorithmunwrappedKeyAlgorithmextractablekeyUsages 参数。

  2. wrappedKey获取传递给 unwrapKey() 方法的 wrappedKey 参数所持有的字节副本 的结果。

  3. normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "unwrapKey"。

  4. 如果发生错误,令 normalizedAlgorithm规范化算法 的结果,其中 alg 设置为 algorithmop 设置为 "decrypt"。

  5. 如果发生错误,则返回一个被 normalizedAlgorithm 拒绝的 Promise。

  6. normalizedKeyAlgorithm规范化算法 的结果,其中 alg 设置为 unwrappedKeyAlgorithmop 设置为 "importKey"。

  7. 如果发生错误,则返回一个被 normalizedKeyAlgorithm 拒绝的 Promise。

  8. realmthis相关领域

  9. promise 为一个新的 Promise。

  10. 返回 promise并行 执行剩余步骤。

  11. 如果以下步骤或引用的过程说明要 抛出 错误,请在 realm 的全局对象上,在 加密任务源排队一个全局任务,以用返回的错误拒绝 promise;然后 终止算法

  12. 如果 normalizedAlgorithmname 成员不等于 unwrappingKey[[algorithm]] 内部槽位的 name 属性,则 抛出 InvalidAccessError

  13. 如果 unwrappingKey[[usages]] 内部槽位不包含 "unwrapKey" 条目,则 抛出 InvalidAccessError

  14. 如果 normalizedAlgorithm 支持解包密钥操作:
    bytes 为执行由 normalizedAlgorithm 指定的解包密钥操作的结果,使用 algorithmunwrappingKey 作为 keywrappedKey 作为 ciphertext
    否则,如果 normalizedAlgorithm 支持解密操作:
    bytes 为执行由 normalizedAlgorithm 指定的解密操作的结果,使用 algorithmunwrappingKey 作为 keywrappedKey 作为 ciphertext
    否则
    抛出 NotSupportedError
  15. 如果 format 等于字符串 "raw"、"pkcs8" 或 "spki":
    keybytes
    如果 format 等于字符串 "jwk":
    key 为执行 解析 JWK 算法的结果,以 bytes 作为要解析的 data
  16. result 为执行由 normalizedKeyAlgorithm 指定的导入密钥操作的结果,使用 unwrappedKeyAlgorithm 作为 algorithmformatusagesextractable,并以 key 作为 keyData

  17. 如果 result[[type]] 内部槽位为 "secret" 或 "private",且 usages 为空,则 抛出 SyntaxError

  18. result[[extractable]] 内部槽位设置为 extractable

  19. result[[usages]] 内部槽位设置为 usages规范化值

  20. realm 的全局对象上,在 加密任务源排队一个全局任务,以执行剩余步骤。

  21. result 为根据 [WebIDL] 的定义,将 result 转换为 realm 中的 ECMAScript 对象的结果。

  22. result 解析 promise

鼓励支持 "raw" 密钥格式以实现互操作性。Web 开发人员应查阅测试套件,获取有关实现对其他密钥格式支持的详细信息。

14.4 异常

SubtleCrypto 接口的方法通过拒绝返回的 Promise 来返回错误,并附带在 ECMAScript [ECMA-262] 或 DOMException 中预定义的异常。使用了以下预定义异常:TypeError。使用了来自 [DOM] 的以下 DOMException 类型:

名称 描述
NotSupportedError 算法不受支持
SyntaxError 必需的参数丢失或超出范围
InvalidAccessError 所请求的操作对于提供的密钥无效
DataError 提供给操作的数据不符合要求
OperationError 由于操作特定的原因,该操作失败

当本规范说明要 抛出 错误时,用户代理必须按 [WebIDL] 中的描述抛出错误。当这种情况发生在子算法中时,这将导致子算法及所有祖先算法的执行终止,直到到达一个明确描述了捕获异常程序的算法。抛出的错误对象应与 this相关领域 相关联。

15. JsonWebKey 字典

WebIDLdictionary RsaOtherPrimesInfo {
  // The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms
  DOMString r;
  DOMString d;
  DOMString t;
};

dictionary JsonWebKey {
  // The following fields are defined in Section 3.1 of JSON Web Key
  DOMString kty;
  DOMString use;
  sequence<DOMString> key_ops;
  DOMString alg;

  // The following fields are defined in JSON Web Key Parameters Registration
  boolean ext;

  // The following fields are defined in Section 6 of JSON Web Algorithms
  DOMString crv;
  DOMString x;
  DOMString y;
  DOMString d;
  DOMString n;
  DOMString e;
  DOMString p;
  DOMString q;
  DOMString dp;
  DOMString dq;
  DOMString qi;
  sequence<RsaOtherPrimesInfo> oth;
  DOMString k;
};

JsonWebKey 字典提供了一种表示和交换由 JSON Web Key [JWK] 结构表示的加密密钥的方法,同时允许在 Web Cryptography API 应用程序中进行原生且高效的使用。

RsaOtherPrimesInfo 的成员定义在 JSON Web Algorithms 的 6.3.2.7 节中。

16. BigInteger

WebIDLtypedef Uint8Array BigInteger;

BigInteger 类型定义是一个 Uint8Array,它以大端顺序保存任意大小的无符号整数。从 API 读取的值 具有最小的类型化数组长度(即最多 7 个前导零位,但值 0 除外,其长度应为 8 位)。API 接受具有任意数量前导零位的值,包括表示零的空数组。

由于该整数是无符号的,最高位不是符号位。在映射到预期为有符号整数的大整数实现时,实现者应格外小心。

17. CryptoKeyPair 字典

WebIDLdictionary CryptoKeyPair {
  CryptoKey publicKey;
  CryptoKey privateKey;
};

CryptoKeyPair 字典表示一个非对称密钥对,它由公钥(publicKey)和私钥(privateKey)组成。

18. 算法

18.1 概述

本节是非规范性的。

除了通过 SubtleCrypto 接口提供执行加密操作的通用接口外,本规范还提供了作者可能希望使用且用户代理(User Agents)可能选择实现的各种算法的描述。这包括一系列常用的对称和非对称算法、密钥派生机制,以及封装和解封装密钥的方法。此外,本规范还定义了一个流程,允许其他规范引入额外的加密算法。

18.2 概念

18.2.1 命名

为 Web Cryptography API 定义的每种加密算法都 必须 拥有一个唯一的名称(称为其 识别算法名称),以确保没有其他规范为 Web Cryptography API 定义相同的、不区分大小写的字符串。

18.2.2 支持的操作

为 Web Cryptography API 定义的每种加密算法都有一个 支持的操作 列表,这是一组由 SubtleCrypto 接口调用的子算法,用于执行所需的加密操作。本规范使用了以下操作

  • encrypt(加密)
  • decrypt(解密)
  • 符号
  • verify(验证)
  • digest(摘要)
  • deriveBits(派生比特)
  • wrapKey(封装密钥)
  • unwrapKey(解封装密钥)
  • generateKey(生成密钥)
  • importKey(导入密钥)
  • exportKey(导出密钥)
  • get key length(获取密钥长度)

如果给定的算法规范没有将特定操作列为受支持,或者明确列为不支持,则用户代理 必须 表现得如同该子算法的调用抛出了 NotSupportedError 一样。

18.2.3 规范化

为 Web Cryptography API 定义的每种加密算法 必须 针对每个 支持的操作 定义用于 算法规范化 的 IDL 类型,以及子算法返回值的 IDL 类型。

18.3 规范约定

本规范中定义的每种加密算法都采用以下规范约定。一个名为 “Registration(注册)” 的章节将包含 识别算法名称。此外,它还包括一个表格,该表格将以行的方式列出每个 支持的操作,并通过 Operation(操作) 列进行标识。给定行的 Parameters(参数) 列的内容将包含用于该操作 算法规范化 的 IDL 类型,该行 Result(结果) 列的内容指示执行该支持操作后所得的 IDL 类型。

如果符合规范的用户代理实现了某种算法,它 必须 实现所有 支持的操作必须 返回指定的 IDL 类型。

此外,在初始化时,符合规范的用户代理必须为每个支持的操作执行 定义算法 步骤,并按照指示注册其 IDL 参数类型。

除非另有说明,否则本规范中由操作创建的对象应与 相关领域(relevant realm) 中的 this 相关联。

18.4 算法规范化

18.4.1 描述

本节是非规范性的。

AlgorithmIdentifier 类型定义允许将算法指定为 DOMString 或对象。DOMString 的使用是为了方便作者为没有参数的算法(例如 SHA-1)提供简写。对象的使用是为了允许指定 Algorithm(或适当的子类),其中包含对象的所有相关参数。

因此,有必要定义将 AlgorithmIdentifier 转换为可与此 API 一起使用的适当字典的算法。该算法必须是可扩展的,以便允许添加新的加密算法;且必须是一致的,以便在将控制权返回给调用脚本之前发生 Web IDL 类型映射,从而防止参数或脚本环境被篡改。

18.4.2 内部状态对象

本规范使用了一个内部对象 supportedAlgorithms。该内部对象不对应用程序公开。

由于此值未对应用程序公开,因此未指定其确切类型。它仅被要求表现为一个键/值对的关联容器,其中键的比较以区分大小写的方式执行。

该内部对象的初始内容如下

  1. 对于 支持的操作 列表中的每个值 v,将内部对象 supportedAlgorithmsv 键设置为一个新的关联容器。

18.4.3 定义算法

定义算法 算法用于规范作者指示用户代理应如何为特定算法规范化参数。其输入是一个表示为 DOMString 的算法名称 alg,一个表示为 DOMString 的操作名称 op,以及所需的 IDL 字典类型 type。该算法的行为如下

  1. registeredAlgorithms 为存储在 supportedAlgorithmsop 键处的关联容器。
  2. registeredAlgorithmsalg 键设置为 IDL 字典类型 type

18.4.4 规范化算法

规范化算法 定义了一个在 Web IDL 转换发生后,将输入强制转换为目标 IDL 字典类型的过程。它被设计为可扩展的,以允许未来规范定义额外算法,并且可以安全地与 Promises 一起使用。其输入是一个操作名称 op 和一个 AlgorithmIdentifier alg。其输出是一个 IDL 字典类型或一个错误。其行为如下

如果 alg 是 DOMString 的实例

返回运行 规范化算法 的结果,将 alg 设置为一个新的 Algorithm 字典(其 name 属性为 alg),并将 op 设置为 op

如果 alg 是一个对象
  1. registeredAlgorithms 为存储在 supportedAlgorithmsop 键处的关联容器。
  2. initialAlg 为将 alg 所表示的 ECMAScript 对象转换为 IDL 字典类型 Algorithm 的结果,如 [WebIDL] 所定义。
  3. 如果发生错误,则返回该错误并终止此算法。
  4. algNameinitialAlgname 属性的值。
  5. 如果 registeredAlgorithms 包含一个与 algName 进行 不区分大小写 字符串匹配的键
    1. algName 设置为该匹配键的值。

    2. desiredType 为存储在 registeredAlgorithmsalgName 处的 IDL 字典类型。

    否则
    返回一个新的 NotSupportedError 并终止此算法。
  6. normalizedAlgorithm 为将 alg 所表示的 ECMAScript 对象转换为 IDL 字典类型 desiredType 的结果,如 [WebIDL] 所定义。
  7. normalizedAlgorithmname 属性设置为 algName
  8. 如果发生错误,则返回该错误并终止此算法。
  9. dictionaries 为一个包含 IDL 字典类型 desiredType 及其所有继承字典的列表,按从派生程度最低到最高排序。
  10. 对于列表中的每个字典 dictionary

    1. 对于在 dictionary 上声明的每个字典成员 member,按顺序执行

      1. keymember 的标识符。
      2. idlValuenormalizedAlgorithm 上键名为 key 的字典成员的值。
      3. 如果 memberBufferSource 类型且存在
        normalizedAlgorithm 上键名为 key 的字典成员设置为 获取由 idlValue 持有的字节副本的结果,替换当前值。
        如果 memberHashAlgorithmIdentifier 类型
        normalizedAlgorithm 上键名为 key 的字典成员设置为 规范化算法 的结果,将 alg 设置为 idlValue,并将 op 设置为 "digest"。
        如果 memberAlgorithmIdentifier 类型
        normalizedAlgorithm 上键名为 key 的字典成员设置为 规范化算法 的结果,将 alg 设置为 idlValue,并将 op 设置为由定义 algName 所标示算法的规范所定义的操作。
      4. 如果发生错误,则返回该错误并终止此算法。
  11. 返回 normalizedAlgorithm

18.5 建议

本节是非规范性的。

18.5.1 致作者

由于此 API 旨在具备可扩展性,为了跟上密码学未来的发展,没有任何算法是符合要求的用户代理必须实现的。因此,作者应检查当前实现推荐和支持的算法。

正如在 安全注意事项 中所强调的,即使是对于一种目的被认为是强大的加密算法,在用于另一种目的时也可能不足。因此,作者在发明新的加密协议之前应极其谨慎。

此外,本规范包含几种在默认使用情况下可能导致加密漏洞的算法。虽然这些问题可以通过结合或组合本规范提供的其他算法来缓解,但作者仍应谨慎行事,并在使用特定算法之前查阅相关的密码学文献。本规范中包含这些算法并不意味着它们适用于任何或所有目的,而仅仅是作为规范,说明如果符合规范的用户代理选择实现该算法,则必须如何实现。

18.5.2 致实现者

为了促进开发者的互操作性,本规范包含了一个建议算法列表。这些被认为是撰写本文时在实践中被最广泛使用的算法,因此为本规范的初始实现提供了一个良好的起点。建议的算法包括

19. 算法概述

本节是非规范性的。

下表概述了本规范中描述的算法,以及该算法可用于的 SubtleCrypto 方法 集。为了将算法与某个方法一起使用,必须在算法规范中定义该方法程序中对应的一个或多个操作。请注意,方法到底层操作的映射并非一一对应

应用程序开发者和脚本作者不应将此表解释为对使用特定算法的建议。相反,它只是记录了哪些方法是受支持的。作者应参考本文档的 面向作者的安全注意事项 章节,以更好地理解使用某些算法时可能出现的风险和担忧。

算法名称 encrypt(加密) decrypt(解密) 符号 verify(验证) digest(摘要) generateKey(生成密钥) deriveKey deriveBits(派生比特) importKey(导入密钥) exportKey(导出密钥) wrapKey(封装密钥) unwrapKey(解封装密钥)
RSASSA-PKCS1-v1_5
RSA-PSS
RSA-OAEP
ECDSA
ECDH
Ed25519
X25519
AES-CTR
AES-CBC
AES-GCM
AES-KW
HMAC
SHA-1
SHA-256
SHA-384
SHA-512
HKDF
PBKDF2

20. RSASSA-PKCS1-v1_5

20.1 描述

本节是非规范性的。

RSASSA-PKCS1-v1_5” 算法标识符用于执行使用 [RFC3447] 中指定的 RSASSA-PKCS1-v1_5 算法,并使用本规范中定义的 SHA 哈希函数的签名和验证。

其他规范 可能会指定将额外的哈希算法与 RSASSA-PKCS1-v1_5 一起使用。此类规范必须为额外的哈希算法定义摘要操作,并为 RSASSA-PKCS1-v1_5 定义 密钥导入步骤密钥导出步骤

20.2 注册

此算法的 识别算法名称 为 “RSASSA-PKCS1-v1_5”。

操作 参数 结果
符号 byte sequence (字节序列)
verify(验证) boolean
generateKey(生成密钥) RsaHashedKeyGenParams CryptoKeyPair
importKey(导入密钥) RsaHashedImportParams CryptoKey
exportKey(导出密钥) object

20.3 RsaKeyGenParams 字典

WebIDLdictionary RsaKeyGenParams : Algorithm {
  required [EnforceRange] unsigned long modulusLength;
  required BigInteger publicExponent;
};

modulusLength 成员包含 RSA 模数的长度(以位为单位)。

publicExponent 成员包含 RSA 公共指数。

20.4 RsaHashedKeyGenParams 字典

WebIDLdictionary RsaHashedKeyGenParams : RsaKeyGenParams {
  required HashAlgorithmIdentifier hash;
};

hash 成员表示要使用的哈希算法。

20.5 RsaKeyAlgorithm 字典

WebIDLdictionary RsaKeyAlgorithm : KeyAlgorithm {
  required unsigned long modulusLength;
  required BigInteger publicExponent;
};

modulusLength 成员包含 RSA 模数的长度(以位为单位)。

publicExponent 成员包含 RSA 公共指数。

20.6 RsaHashedKeyAlgorithm 字典

WebIDLdictionary RsaHashedKeyAlgorithm : RsaKeyAlgorithm {
  required KeyAlgorithm hash;
};

hash 成员描述了此密钥所使用的哈希算法。

20.7 RsaHashedImportParams 字典

WebIDLdictionary RsaHashedImportParams : Algorithm {
  required HashAlgorithmIdentifier hash;
};

hash 成员描述了要使用的哈希算法。

20.8 操作

20.8.1 签名 (Sign)

  1. 如果 key[[type]] 内部槽不是 “private”,则 抛出 InvalidAccessError

  2. 执行 [RFC3447] 第 8.2 节中定义的签名生成操作,使用由 key[[handle]] 内部槽表示的密钥作为签名者的私钥,message 作为 M,并使用指定在 key[[algorithm]] 内部槽的 hash 属性中的哈希函数作为 EMSA-PKCS1-v1_5 编码方法的 Hash 选项。

  3. 如果执行该操作导致错误,则 抛出 OperationError

  4. signature 为执行该操作后得到的 S 值。

  5. 返回 signature

20.8.2 验证 (Verify)

  1. 如果 key[[type]] 内部槽不是 “public”,则 抛出 InvalidAccessError

  2. 执行 [RFC3447] 第 8.2 节中定义的签名验证操作,使用由 key[[handle]] 内部槽表示的密钥作为签名者的 RSA 公钥,message 作为 Msignature 作为 S,并使用指定在 key[[algorithm]] 内部槽的 hash 属性中的哈希函数作为 EMSA-PKCS1-v1_5 编码方法的 Hash 选项。

  3. result 为布尔值,如果操作结果为 “valid signature(有效签名)”,则值为 true,否则为 false。

  4. 返回 result

20.8.3 生成密钥 (Generate Key)

  1. 如果 usages 包含一个非 “sign” 或 “verify” 的条目,则 抛出 SyntaxError

  2. 生成一个 RSA 密钥对,如 [RFC3447] 中所定义,RSA 模数长度等于 normalizedAlgorithmmodulusLength 属性,RSA 公共指数等于 normalizedAlgorithmpublicExponent 属性。

  3. 如果密钥对生成失败,则 抛出 OperationError

  4. algorithm 为一个新的 RsaHashedKeyAlgorithm 字典。

  5. algorithmname 属性设置为 “RSASSA-PKCS1-v1_5”。

  6. algorithmmodulusLength 属性设置为等于 normalizedAlgorithmmodulusLength 属性。

  7. algorithmpublicExponent 属性设置为等于 normalizedAlgorithmpublicExponent 属性。

  8. algorithmhash 属性设置为等于 normalizedAlgorithmhash 成员。

  9. publicKey 为一个新的 CryptoKey,表示生成的密钥对中的公钥。

  10. publicKey[[type]] 内部槽设置为 “public

  11. publicKey[[algorithm]] 内部槽设置为 algorithm

  12. publicKey[[extractable]] 内部槽设置为 true。

  13. publicKey[[usages]] 内部槽设置为 usages[ "verify" ]用法交集

  14. privateKey 为一个新的 CryptoKey,表示生成的密钥对中的私钥。

  15. privateKey[[type]] 内部槽设置为 “private

  16. privateKey[[algorithm]] 内部槽设置为 algorithm

  17. privateKey[[extractable]] 内部槽设置为 extractable

  18. privateKey[[usages]] 内部槽设置为 usages[ "sign" ]用法交集

  19. result 为一个新的 CryptoKeyPair 字典。

  20. resultpublicKey 属性设置为 publicKey

  21. resultprivateKey 属性设置为 privateKey

  22. 返回 result

20.8.4 导入密钥 (Import Key)

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 “spki
    1. 如果 usages 包含一个非 “verify” 的条目,则 抛出 SyntaxError

    2. spki 为对 keyData 运行 解析 subjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. publicKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataspkisubjectPublicKeyInfo 字段,structure 为 [RFC3447] A.1.1 节中指定的 RSAPublicKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者确定 publicKey 根据 [RFC3447] 不是有效的公钥,则 抛出 DataError

    7. key 为一个新的 CryptoKey,表示由 publicKey 标识的 RSA 公钥。

    8. key[[type]] 内部槽设置为 “public

    如果 format 为 “pkcs8
    1. 如果 usages 包含一个非 “sign” 的条目,则 抛出 SyntaxError

    2. privateKeyInfo 为对 keyData 运行 解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. rsaPrivateKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC3447] A.1.2 节中指定的 RSAPrivateKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者如果 rsaPrivateKey 根据 [RFC3447] 不是有效的 RSA 私钥,则 抛出 DataError

    7. key 为一个新的 CryptoKey,表示由 rsaPrivateKey 标识的 RSA 私钥。

    8. key[[type]] 内部槽设置为 “private

    如果 format 为 “jwk
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkd 字段存在且 usages 包含一个非 “sign” 的条目;或者,如果 jwkd 字段不存在且 usages 包含一个非 “verify” 的条目,则 抛出 SyntaxError

    3. 如果 jwkkty 字段不是与 “RSA” 进行大小写敏感匹配的字符串,则 抛出 DataError

    4. 如果 usages 非空,且 jwkuse 字段存在,且不是与 “sig” 进行大小写敏感匹配的字符串,则 抛出 DataError

    5. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求是无效的,或者不包含所有指定的 usages 值,则 抛出 DataError

    6. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 DataError

    7. hash 为一个初始值未定义的字符串。

    8. 如果 jwkalg 字段不存在

      hash 为未定义。

      如果 alg 字段等于字符串 “RS1

      hash 为字符串 “SHA-1”。

      如果 alg 字段等于字符串 “RS256

      hash 为字符串 “SHA-256”。

      如果 alg 字段等于字符串 “RS384

      hash 为字符串 “SHA-384”。

      如果 alg 字段等于字符串 “RS512

      hash 为字符串 “SHA-512”。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatjwk,并获取 hash

      2. 如果发生错误或不存在 适用规范,则 抛出 DataError

    9. 如果 hash 不为未定义
      1. normalizedHash规范化算法 的结果,将 alg 设置为 hash,将 op 设置为 digest

      2. 如果 normalizedHash 不等于 normalizedAlgorithmhash 成员,则 抛出 DataError

    10. 如果 jwkd 字段存在
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.2 节的要求,则 抛出 DataError

      2. privateKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.2 节解释 jwk 所确定的 RSA 私钥。

      3. 如果 privateKey 根据 [RFC3447] 不是有效的 RSA 私钥,则 抛出 DataError

      4. key 为一个新的 CryptoKey 对象,表示 privateKey

      5. key[[type]] 内部槽设置为 “private

      否则
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.1 节的要求,则 抛出 DataError

      2. publicKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.1 节解释 jwk 所确定的 RSA 公钥。

      3. 如果可以确定 publicKey 根据 [RFC3447] 不是有效的 RSA 公钥,则 抛出 DataError

      4. key 为一个新的 CryptoKey,表示 publicKey

      5. key[[type]] 内部槽设置为 “public

    否则
    抛出 NotSupportedError
  3. algorithm 为一个新的 RsaHashedKeyAlgorithm 字典。

  4. algorithmname 属性设置为 “RSASSA-PKCS1-v1_5

  5. algorithmmodulusLength 属性设置为 RSA 公共模数的长度(以位为单位)。

  6. algorithmpublicExponent 属性设置为 RSA 公共指数的 BigInteger 表示。

  7. algorithmhash 属性设置为 normalizedAlgorithmhash 成员。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

20.8.5 导出密钥 (Export Key)

  1. key 为要导出的密钥。

  2. 如果无法访问由 key[[handle]] 内部槽表示的基础加密密钥材料,则 抛出 OperationError

  3. 如果 format 为 “spki
    1. 如果 key[[type]] 内部槽不是 “public”,则 抛出 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • subjectPublicKey 字段设置为对 [RFC3447] 附录 A.1.1 中定义的 RSAPublicKey ASN.1 类型进行 DER 编码的结果,该类型表示由 key[[handle]] 内部槽表示的 RSA 公钥。

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 “pkcs8
    1. 如果 key[[type]] 内部槽不是 “private”,则 抛出 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • privateKey 字段设置为对 [RFC3447] 附录 A.1.2 中定义的 RSAPrivateKey ASN.1 类型进行 DER 编码的结果,该类型表示由 key[[handle]] 内部槽表示的 RSA 私钥。

        [RFC5208] 在第 5 节中指定(作为“例如”)此字段的编码应为 BER 编码。然而,为了避免要求 WebCrypto 实现支持 BER 编码和 BER 解码,仅生产或接受 DER 编码。
    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 “jwk
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 “RSA”。

    3. hashkey[[algorithm]] 内部槽的 hash 属性的 name 属性。

    4. 如果 hash 为 “SHA-1

      jwkalg 属性设置为字符串 “RS1”。

      如果 hash 为 “SHA-256

      jwkalg 属性设置为字符串 “RS256”。

      如果 hash 为 “SHA-384

      jwkalg 属性设置为字符串 “RS384”。

      如果 hash 为 “SHA-512

      jwkalg 属性设置为字符串 “RS512”。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey,并获取 alg

      2. 如果发生错误或不存在 适用规范,则 抛出 NotSupportedError

      3. jwkalg 属性设置为 alg

    5. 根据 JSON Web Algorithms [JWA] 第 6.3.1 节中的相应定义,设置 jwkne 属性。

    6. 如果 key[[type]] 内部槽为 “private
      1. 根据 JSON Web Algorithms [JWA] 第 6.3.2 节中的相应定义,设置 jwk 中名为 dpqdpdqqi 的属性。

      2. 如果由 key[[handle]] 内部槽表示的基础 RSA 私钥由超过两个素数表示,根据 JSON Web Algorithms [JWA] 第 6.3.2.7 节中的相应定义,设置 jwk 中名为 oth 的属性。

    7. jwkkey_ops 属性设置为 keyusages 属性。

    8. jwkext 属性设置为 key[[extractable]] 内部槽。

    9. resultjwk

    否则

    抛出 NotSupportedError

  4. 返回 result

21. RSA-PSS

21.1 描述

本节是非规范性的。

RSA-PSS” 算法标识符用于执行使用 [RFC3447] 中指定的 RSASSA-PSS 算法,并使用本规范中定义的 SHA 哈希函数和掩码生成公式 MGF1 的签名和验证。

其他规范 可能会指定将额外的哈希算法与 RSASSA-PSS 一起使用。此类规范必须为额外的哈希算法定义摘要操作,并为 RSASSA-PSS 定义 密钥导入步骤密钥导出步骤

21.2 注册

此算法的 识别算法名称 为 “RSA-PSS”。

操作 参数 结果
符号 RsaPssParams byte sequence (字节序列)
verify(验证) RsaPssParams boolean
generateKey(生成密钥) RsaHashedKeyGenParams CryptoKeyPair
importKey(导入密钥) RsaHashedImportParams CryptoKey
exportKey(导出密钥) object

21.3 RsaPssParams 字典

WebIDLdictionary RsaPssParams : Algorithm {
  required [EnforceRange] unsigned long saltLength;
};

saltLength 成员表示随机盐的期望长度(以字节为单位)。

21.4 操作

21.4.1 签名

  1. 如果 key[[type]] 内部槽不是 “private”,则 抛出 InvalidAccessError

  2. 执行 [RFC3447] 第 8.1 节中定义的签名生成操作,使用由 key[[handle]] 内部槽表示的密钥作为签名者的私钥 Kmessage 作为要签名的消息 M,并使用指定在 key[[algorithm]] 内部槽的 hash 属性中的哈希函数作为 Hash 选项,MGF1(定义在 [RFC3447] 的 B.2.1 节中)作为 MGF 选项,以及 normalizedAlgorithmsaltLength 成员作为 EMSA-PSS-ENCODE 操作的盐长度选项。

  3. 如果执行该操作导致错误,则 抛出 OperationError

  4. signature 为执行该操作后得到的签名 S

  5. 返回 signature

21.4.2 验证

  1. 如果 key[[type]] 内部槽不是 “public”,则 抛出 InvalidAccessError

  2. 执行 [RFC3447] 第 8.1 节中定义的签名验证操作,使用由 key[[handle]] 内部槽表示的密钥作为签名者的 RSA 公钥,message 作为 Msignature 作为 S,并使用指定在 key[[algorithm]] 内部槽的 hash 属性中的哈希函数作为 Hash 选项,MGF1(定义在 [RFC3447] 的 B.2.1 节中)作为 MGF 选项,以及 normalizedAlgorithmsaltLength 成员作为 EMSA-PSS-VERIFY 操作的盐长度选项。

  3. result 为布尔值,如果操作结果为 “valid signature(有效签名)”,则值为 true,否则为 false。

21.4.3 生成密钥

  1. 如果 usages 包含一个非 “sign” 或 “verify” 的条目,则 抛出 SyntaxError

  2. 生成一个 RSA 密钥对,如 [RFC3447] 中所定义,RSA 模数长度等于 normalizedAlgorithmmodulusLength 成员,RSA 公共指数等于 normalizedAlgorithmpublicExponent 成员。

  3. 如果执行该操作导致错误,则 抛出 OperationError

  4. algorithm 为一个新的 RsaHashedKeyAlgorithm 字典。

  5. algorithmname 属性设置为 “RSA-PSS”。

  6. algorithmmodulusLength 属性设置为等于 normalizedAlgorithmmodulusLength 成员。

  7. algorithmpublicExponent 属性设置为等于 normalizedAlgorithmpublicExponent 成员。

  8. algorithmhash 属性设置为等于 normalizedAlgorithmhash 成员。

  9. publicKey 为一个新的 CryptoKey,表示生成的密钥对中的公钥。

  10. publicKey[[type]] 内部槽设置为 “public

  11. publicKey[[algorithm]] 内部槽设置为 algorithm

  12. publicKey[[extractable]] 内部槽设置为 true。

  13. publicKey[[usages]] 内部槽设置为 usages[ "verify" ]用法交集

  14. privateKey 为一个新的 CryptoKey,表示生成的密钥对中的私钥。

  15. privateKey[[type]] 内部槽设置为 “private

  16. privateKey[[algorithm]] 内部槽设置为 algorithm

  17. privateKey[[extractable]] 内部槽设置为 extractable

  18. privateKey[[usages]] 内部槽设置为 usages[ "sign" ]用法交集

  19. result 为一个新的 CryptoKeyPair 字典。

  20. resultpublicKey 属性设置为 publicKey

  21. resultprivateKey 属性设置为 privateKey

  22. 返回 result

21.4.4 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 “spki
    1. 如果 usages 包含一个非 “verify” 的条目,则 抛出 SyntaxError

    2. spki 为对 keyData 运行 解析 subjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. publicKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataspkisubjectPublicKeyInfo 字段,structure 为 [RFC3447] A.1.1 节中指定的 RSAPublicKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者确定 publicKey 根据 [RFC3447] 不是有效的公钥,则 抛出 DataError

    7. key 为一个新的 CryptoKey,表示由 publicKey 标识的 RSA 公钥。

    8. key[[type]] 内部槽设置为 “public

    如果 format 为 “pkcs8
    1. 如果 usages 包含一个非 “sign” 的条目,则 抛出 SyntaxError

    2. privateKeyInfo 为对 keyData 运行 解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. rsaPrivateKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC3447] A.1.2 节中指定的 RSAPrivateKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者如果 rsaPrivateKey 根据 [RFC3447] 不是有效的 RSA 私钥,则 抛出 DataError

    7. key 为一个新的 CryptoKey,表示由 rsaPrivateKey 标识的 RSA 私钥。

    8. key[[type]] 内部槽设置为 “private

    如果 format 为 “jwk
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkd 字段存在且 usages 包含一个非 “sign” 的条目;或者,如果 jwkd 字段不存在且 usages 包含一个非 “verify” 的条目,则 抛出 SyntaxError

    3. 如果 jwkkty 字段与“RSA”字符串的大小写敏感匹配不符,则抛出一个 DataError

    4. 如果 usages 非空,且 jwk 中存在 use 字段,但该字段与“sig”字符串的大小写敏感匹配不符,则抛出一个 DataError

    5. 如果 jwk 中存在 key_ops 字段,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    6. 如果 jwk 中存在 ext 字段且其值为 false,同时 extractable 为 true,则抛出一个 DataError

    7. 如果 jwk 中不存在 alg 字段

      hash 为未定义。

      如果 alg 字段等于字符串“PS1

      hash 为字符串 “SHA-1”。

      如果 alg 字段等于字符串“PS256

      hash 为字符串 “SHA-256”。

      如果 alg 字段等于字符串“PS384

      hash 为字符串 “SHA-384”。

      如果 alg 字段等于字符串“PS512

      hash 为字符串 “SHA-512”。

      否则
      1. 执行由其他适用规范定义的任何密钥导入步骤,传入 formatjwk 并获取 hash

      2. 如果发生错误或没有适用规范,则抛出一个 DataError

    8. 如果 hash 不为未定义
      1. normalizedHash规范化算法的结果,其中将 alg 设置为 hash,并将 op 设置为 digest

      2. 如果 normalizedHash 不等于 normalizedAlgorithmhash 成员,则抛出一个 DataError

    9. 如果 jwk 中存在 d 字段
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.2 节的要求,则 抛出 DataError

      2. privateKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.2 节解析 jwk 所标识的 RSA 私钥。

      3. 如果根据 [RFC3447] 可以确定 privateKey 不是有效的 RSA 私钥,则抛出一个 DataError

      4. key 为表示 privateKey 的新 CryptoKey

      5. key[[type]] 内部槽设置为“private

      否则
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.1 节的要求,则 抛出 DataError

      2. publicKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.1 节解释 jwk 所确定的 RSA 公钥。

      3. 如果可以确定 publicKey 根据 [RFC3447] 不是有效的 RSA 公钥,则 抛出 DataError

      4. key 为表示 publicKey 的新 CryptoKey

      5. key[[type]] 内部槽设置为“public

    否则
    抛出 NotSupportedError
  3. algorithm 为一个新的 RsaHashedKeyAlgorithm 字典。

  4. algorithmname 属性设置为“RSA-PSS

  5. algorithmmodulusLength 属性设置为 RSA 公钥模数的位长度。

  6. algorithmpublicExponent 属性设置为 RSA 公钥指数的 BigInteger 表示。

  7. algorithmhash 属性设置为 normalizedAlgorithmhash 成员。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

21.4.5 导出密钥

  1. key 为要导出的密钥。

  2. 如果无法访问由 key[[handle]] 内部槽表示的基础加密密钥材料,则抛出一个 OperationError

  3. 如果 format 是“spki
    1. 如果 key[[type]] 内部槽不是“public”,则抛出一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • subjectPublicKey 字段设置为对 RSAPublicKey ASN.1 类型进行 DER 编码的结果(如 [RFC3447] 附录 A.1.1 所定义),该类型表示由 key[[handle]] 内部槽表示的 RSA 公钥。

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 是“pkcs8
    1. 如果 key[[type]] 内部槽不是“private”,则抛出一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • privateKey 字段设置为对 RSAPrivateKey ASN.1 类型进行 DER 编码的结果(如 [RFC3447] 附录 A.1.2 所定义),该类型表示由 key[[handle]] 内部槽表示的 RSA 私钥。

        [RFC5208] 在第 5 节中指定(作为“例如”)此字段的编码应为 BER 编码。然而,为了避免要求 WebCrypto 实现支持 BER 编码和 BER 解码,仅生产或接受 DER 编码。
    3. result 为对 data 进行 DER 编码的结果。

    如果 format 是“jwk
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 “RSA”。

    3. hashkey[[algorithm]] 内部槽的 hash 属性的 name 属性。

    4. 如果 hash 为 “SHA-1

      jwkalg 属性设置为字符串“PS1”。

      如果 hash 为 “SHA-256

      jwkalg 属性设置为字符串“PS256”。

      如果 hash 为 “SHA-384

      jwkalg 属性设置为字符串“PS384”。

      如果 hash 为 “SHA-512

      jwkalg 属性设置为字符串“PS512”。

      否则
      1. 执行由其他适用规范定义的任何密钥导出步骤,传入 formatkey[[algorithm]] 内部槽的 hash 属性,并获取 alg

      2. jwkalg 属性设置为 alg

    5. 根据 JSON Web Algorithms [JWA] 第 6.3.1 节中的相应定义,设置 jwk 的属性 ne

    6. 如果 key[[type]] 内部槽为“private
      1. 根据 JSON Web Algorithms [JWA] 第 6.3.2 节中的相应定义,设置 jwk 名为 dpqdpdqqi 的属性。

      2. 如果由 key[[handle]] 内部槽表示的基础 RSA 私钥由两个以上的素数表示,则根据 JSON Web Algorithms [JWA] 第 6.3.2.7 节中的相应定义,设置 jwk 名为 oth 的属性。

    7. jwkkey_ops 属性设置为 keyusages 属性。

    8. jwkext 属性设置为 key[[extractable]] 内部槽。

    9. resultjwk

    否则

    抛出 NotSupportedError

  4. 返回 result

22. RSA-OAEP

22.1 描述

本节是非规范性的。

RSA-OAEP”算法标识符用于执行加密和解密,以符合 [RFC3447] 中指定的 RSAES-OAEP 算法,使用本规范中定义的 SHA 哈希函数和掩码生成函数 MGF1。

其他规范可以指定将额外的哈希算法用于 RSAES-OAEP。此类规范必须为额外的哈希算法定义摘要操作,并为 RSAES-OAEP 定义密钥导入步骤密钥导出步骤

22.2 注册

此算法的公认算法名称为“RSA-OAEP”。

操作 参数 结果
encrypt(加密) RsaOaepParams byte sequence (字节序列)
decrypt(解密) RsaOaepParams byte sequence (字节序列)
generateKey(生成密钥) RsaHashedKeyGenParams CryptoKeyPair
importKey(导入密钥) RsaHashedImportParams CryptoKey
exportKey(导出密钥) object

22.3 RsaOaepParams 字典

WebIDLdictionary RsaOaepParams : Algorithm {
  BufferSource label;
};

成员 label 表示与消息关联的可选标签/应用程序数据。

22.4 操作

22.4.1 加密 (Encrypt)

  1. 如果 key[[type]] 内部槽不是“public”,则抛出一个 InvalidAccessError

  2. labelnormalizedAlgorithmlabel 成员,如果 normalizedAlgorithm 中不存在 label 成员,则为由空字节序列。

  3. 执行 [RFC3447] 第 7.1 节中定义的加密操作,使用由 key 表示的密钥作为接收者的 RSA 公钥,plaintext 作为要加密的消息 Mlabel 作为标签 L,并使用由 key[[algorithm]] 内部槽的 hash 属性指定的哈希函数作为 Hash 选项,并使用 MGF1(在 [RFC3447] 第 B.2.1 节中定义)作为 MGF 选项。

  4. 如果执行该操作导致错误,则 抛出 OperationError

  5. ciphertext 为执行该操作后得到的 C 值。

  6. 返回 ciphertext

22.4.2 解密 (Decrypt)

  1. 如果 key[[type]] 内部槽不是“private”,则抛出一个 InvalidAccessError

  2. labelnormalizedAlgorithmlabel 成员,如果 normalizedAlgorithm 中不存在 label 成员,则为由空字节序列。

  3. 执行 [RFC3447] 第 7.1 节中定义的解密操作,使用由 key 表示的密钥作为接收者的 RSA 私钥,ciphertext 作为要解密的密文 Clabel 作为标签 L,并使用由 key[[algorithm]] 内部槽的 hash 属性指定的哈希函数作为 Hash 选项,并使用 MGF1(在 [RFC3447] 第 B.2.1 节中定义)作为 MGF 选项。

  4. 如果执行该操作导致错误,则 抛出 OperationError

  5. plaintext 为执行该操作后得到的 M 值。

  6. 返回 plaintext

22.4.3 生成密钥

  1. 如果 usages 包含一个不是“encrypt”、“decrypt”、“wrapKey”或“unwrapKey”的条目,则抛出一个 SyntaxError

  2. 生成一个 RSA 密钥对(如 [RFC3447] 中定义),其 RSA 模数长度等于 normalizedAlgorithmmodulusLength 成员,且 RSA 公钥指数等于 normalizedAlgorithmpublicExponent 成员。

  3. 如果执行该操作导致错误,则 抛出 OperationError

  4. algorithm 为一个新的 RsaHashedKeyAlgorithm 对象。

  5. algorithmname 属性设置为“RSA-OAEP”。

  6. algorithmmodulusLength 属性设置为等于 normalizedAlgorithmmodulusLength 成员。

  7. algorithmpublicExponent 属性设置为等于 normalizedAlgorithmpublicExponent 成员。

  8. algorithmhash 属性设置为等于 normalizedAlgorithmhash 成员。

  9. publicKey 为表示所生成密钥对的公钥的新 CryptoKey

  10. publicKey[[type]] 内部槽设置为“public

  11. publicKey[[algorithm]] 内部槽设置为 algorithm

  12. publicKey[[extractable]] 内部槽设置为 true。

  13. publicKey[[usages]] 内部槽设置为 usages[ "encrypt", "wrapKey" ]用法交集

  14. privateKey 为表示所生成密钥对的私钥的新 CryptoKey

  15. privateKey[[type]] 内部槽设置为“private

  16. privateKey[[algorithm]] 内部槽设置为 algorithm

  17. privateKey[[extractable]] 内部槽设置为 extractable

  18. privateKey[[usages]] 内部槽设置为 usages[ "decrypt", "unwrapKey" ]用法交集

  19. result 为一个新的 CryptoKeyPair 字典。

  20. resultpublicKey 属性设置为 publicKey

  21. resultprivateKey 属性设置为 privateKey

  22. 返回 result

22.4.4 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 是“spki
    1. 如果 usages 包含一个不是“encrypt”或“wrapKey”的条目,则抛出一个 SyntaxError

    2. spki 为对 keyData 运行解析 subjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. publicKey 为执行解析 ASN.1 结构算法的结果,其中 dataspkisubjectPublicKeyInfo 字段,structure 为 [RFC3447] A.1.1 节中指定的 RSAPublicKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者确定 publicKey 根据 [RFC3447] 不是有效的公钥,则 抛出 DataError

    7. key 为一个表示由 publicKey 标识的 RSA 公钥的新 CryptoKey

    8. key[[type]] 内部槽设置为“public

    如果 format 是“pkcs8
    1. 如果 usages 包含一个不是“decrypt”或“unwrapKey”的条目,则抛出一个 SyntaxError

    2. privateKeyInfo 为对 keyData 运行解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC3447] 中定义的 rsaEncryption 对象标识符,则 抛出 DataError

    5. rsaPrivateKey 为执行解析 ASN.1 结构算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC3447] A.1.2 节中指定的 RSAPrivateKey 结构,并将 exactData 设置为 true。

    6. 如果解析时发生错误,或者如果 rsaPrivateKey 根据 [RFC3447] 不是有效的 RSA 私钥,则 抛出 DataError

    7. key 为一个表示由 rsaPrivateKey 标识的 RSA 私钥的新 CryptoKey

    8. key[[type]] 内部槽设置为“private

    如果 format 是“jwk
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwk 中存在 d 字段,且 usages 包含一个不是“decrypt”或“unwrapKey”的条目,则抛出一个 SyntaxError

    3. 如果 jwk 中不存在 d 字段,且 usages 包含一个不是“encrypt”或“wrapKey”的条目,则抛出一个 SyntaxError

    4. 如果 jwkkty 字段与“RSA”字符串的大小写敏感匹配不符,则抛出一个 DataError

    5. 如果 usages 非空,且 jwk 中存在 use 字段,但该字段与“enc”字符串的大小写敏感匹配不符,则抛出一个 DataError

    6. 如果 jwk 中存在 key_ops 字段,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    7. 如果 jwk 中存在 ext 字段且其值为 false,同时 extractable 为 true,则抛出一个 DataError

    8. 如果 jwkalg 字段不存在
      hash 为未定义。
      如果 jwkalg 字段等于“RSA-OAEP
      hash 为字符串 “SHA-1”。
      如果 jwkalg 字段等于“RSA-OAEP-256
      hash 为字符串 “SHA-256”。
      如果 jwkalg 字段等于“RSA-OAEP-384
      hash 为字符串 “SHA-384”。
      如果 jwkalg 字段等于“RSA-OAEP-512
      hash 为字符串 “SHA-512”。
      否则
      1. 执行由其他适用规范定义的任何密钥导入步骤,传入 formatjwk 并获取 hash

      2. 如果发生错误或没有适用规范,则抛出一个 DataError

    9. 如果 hash 不为未定义
      1. normalizedHash规范化算法的结果,其中将 alg 设置为 hash,并将 op 设置为 digest

      2. 如果 normalizedHash 不等于 normalizedAlgorithmhash 成员,则抛出一个 DataError

    10. 如果 jwk 中存在 d 字段
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.2 节的要求,则 抛出 DataError

      2. privateKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.2 节解析 jwk 所标识的 RSA 私钥。

      3. 如果根据 [RFC3447] 可以确定 privateKey 不是有效的 RSA 私钥,则抛出一个 DataError

      4. key 为表示 privateKey 的新 CryptoKey

      5. key[[type]] 内部槽设置为“private

      否则
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.3.1 节的要求,则 抛出 DataError

      2. publicKey 表示通过根据 JSON Web Algorithms [JWA] 第 6.3.1 节解释 jwk 所确定的 RSA 公钥。

      3. 如果可以确定 publicKey 根据 [RFC3447] 不是有效的 RSA 公钥,则 抛出 DataError

      4. key 为表示 publicKey 的新 CryptoKey

      5. key[[type]] 内部槽设置为“public

    否则
    抛出 NotSupportedError
  3. algorithm 为一个新的 RsaHashedKeyAlgorithm

  4. algorithmname 属性设置为“RSA-OAEP

  5. algorithmmodulusLength 属性设置为 RSA 公钥模数的位长度。

  6. algorithmpublicExponent 属性设置为 RSA 公钥指数的 BigInteger 表示。

  7. algorithmhash 属性设置为 normalizedAlgorithmhash 成员。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

22.4.5 导出密钥

  1. key 为要导出的密钥。

  2. 如果无法访问由 key[[handle]] 内部槽表示的基础加密密钥材料,则抛出一个 OperationError

  3. 如果 format 是“spki
    1. 如果 key[[type]] 内部槽不是“public”,则抛出一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • subjectPublicKey 字段设置为对 RSAPublicKey ASN.1 类型进行 DER 编码的结果(如 [RFC3447] 附录 A.1.1 所定义),该类型表示由 key[[handle]] 内部槽表示的 RSA 公钥。

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 是“pkcs8
    1. 如果 key[[type]] 内部槽不是“private”,则抛出一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC3447] 中定义的 OID rsaEncryption

        • params 字段设置为 ASN.1 类型 NULL。

      • privateKey 字段设置为对 RSAPrivateKey ASN.1 类型进行 DER 编码的结果(如 [RFC3447] 附录 A.1.2 所定义),该类型表示由 key[[handle]] 内部槽表示的 RSA 私钥。

        [RFC5208] 在第 5 节中指定(作为“例如”)此字段的编码应为 BER 编码。然而,为了避免要求 WebCrypto 实现支持 BER 编码和 BER 解码,仅生产或接受 DER 编码。
    3. result 为对 data 进行 DER 编码的结果。

    如果 format 是“jwk
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 “RSA”。

    3. hashkey[[algorithm]] 内部槽的 hash 属性的 name 属性。

    4. 如果 hash 为 “SHA-1

      jwkalg 属性设置为字符串“RSA-OAEP”。

      如果 hash 为 “SHA-256

      jwkalg 属性设置为字符串“RSA-OAEP-256”。

      如果 hash 为 “SHA-384

      jwkalg 属性设置为字符串“RSA-OAEP-384”。

      如果 hash 为 “SHA-512

      jwkalg 属性设置为字符串“RSA-OAEP-512”。

      否则
      1. 执行由其他适用规范定义的任何密钥导出步骤,传入 formatkey[[algorithm]] 内部槽的 hash 属性,并获取 alg

      2. jwkalg 属性设置为 alg

    5. 根据 JSON Web Algorithms [JWA] 第 6.3.1 节中的相应定义,设置 jwk 的属性 ne

    6. 如果 key[[type]] 内部槽为“private
      1. 根据 JSON Web Algorithms [JWA] 第 6.3.2 节中的相应定义,设置 jwk 名为 dpqdpdqqi 的属性。

      2. 如果由 key[[handle]] 内部槽表示的基础 RSA 私钥由两个以上的素数表示,则根据 JSON Web Algorithms [JWA] 第 6.3.2.7 节中的相应定义,设置 jwk 名为 oth 的属性。

    7. jwkkey_ops 属性设置为 keyusages 属性。

    8. jwkext 属性设置为 key[[extractable]] 内部槽。

    9. resultjwk

    否则

    抛出 NotSupportedError

  4. 返回 result

23. ECDSA

23.1 描述

本节是非规范性的。

ECDSA”算法标识符用于执行签名和验证,使用 [RFC6090] 中指定的 ECDSA 算法,并使用本规范中定义的 SHA 哈希函数和椭圆曲线。

其他规范可以指定将额外的椭圆曲线和哈希算法用于 ECDSA。为了指定与 ECDSA 一起使用的额外哈希算法,规范必须定义一个支持摘要操作的已注册算法。为了指定额外的椭圆曲线,规范必须定义曲线名称ECDSA 签名步骤ECDSA 验证步骤ECDSA 生成步骤ECDSA 密钥导入步骤ECDSA 密钥导出步骤

23.2 注册

此算法的公认算法名称为“ECDSA”。

操作 参数 结果
符号 EcdsaParams byte sequence (字节序列)
verify(验证) EcdsaParams boolean
generateKey(生成密钥) EcKeyGenParams CryptoKeyPair
importKey(导入密钥) EcKeyImportParams CryptoKey
exportKey(导出密钥) object

23.3 EcdsaParams 字典

WebIDLdictionary EcdsaParams : Algorithm {
  required HashAlgorithmIdentifier hash;
};

成员 hash 表示要使用的哈希算法。

23.4 EcKeyGenParams 字典

WebIDLtypedef DOMString NamedCurve;

dictionary EcKeyGenParams : Algorithm {
  required NamedCurve namedCurve;
};

类型 NamedCurve 表示命名椭圆曲线,这是一种指定知名椭圆曲线域参数的便捷方式。以下值为本规范所定义:

P-256
NIST 推荐的曲线 P-256,也称为 secp256r1
P-384
NIST 推荐的曲线 P-384,也称为 secp384r1
P-521
NIST 推荐的曲线 P-521,也称为 secp521r1

其他规范可以定义额外的值

EcKeyGenParams 字典的 namedCurve 成员表示命名曲线。

23.5 EcKeyAlgorithm 字典

WebIDLdictionary EcKeyAlgorithm : KeyAlgorithm {
  required NamedCurve namedCurve;
};

成员 namedCurve 表示密钥使用的命名曲线。

23.6 EcKeyImportParams 字典

WebIDLdictionary EcKeyImportParams : Algorithm {
  required NamedCurve namedCurve;
};

成员 namedCurve 表示命名曲线。

23.7 操作

23.7.1 签名

  1. 如果 key[[type]] 内部槽不是“private”,则抛出一个 InvalidAccessError

  2. hashAlgorithmnormalizedAlgorithmhash 成员。

  3. M 为使用 message 执行 hashAlgorithm 指定的摘要操作的结果。

  4. d 为与 key 关联的 ECDSA 私钥。

  5. params 为与 key 关联的 EC 域参数。

  6. 如果 key[[algorithm]] 内部槽的 namedCurve 属性为“P-256”、“P-384”或“P-521
    1. 执行 ECDSA 签名过程(如 [RFC6090] 第 5.4 节所指定),以 M 为消息,使用 params 作为 EC 域参数,并以 d 作为私钥。

    2. rs 为执行 ECDSA 签名过程得到的整数对。

    3. result 为一个空的 字节序列

    4. n 为最小整数,使得 n * 8 大于由 params 标识的椭圆曲线基点阶数的以 2 为底的对数。

    5. r 转换为长度为 n 的字节序列,并将其附加到 result

    6. s 转换为长度为 n 的字节序列,并将其附加到 result

    否则,key[[algorithm]] 内部槽的 namedCurve 属性为适用规范中指定的值

    执行该规范中指定的 ECDSA 签名步骤,传入 Mparamsd,并得出 result

  7. 返回 result

23.7.2 验证

  1. 如果 key[[type]] 内部槽不是“public”,则抛出一个 InvalidAccessError

  2. hashAlgorithmnormalizedAlgorithmhash 成员。

  3. M 为使用 message 执行 hashAlgorithm 指定的摘要操作的结果。

  4. Q 为与 key 关联的 ECDSA 公钥。

  5. params 为与 key 关联的 EC 域参数。

  6. 如果 key[[algorithm]] 内部槽的 namedCurve 属性为“P-256”、“P-384”或“P-521

    执行 ECDSA 验证过程(如 [RFC6090] 第 5.3 节所指定),以 M 为接收到的消息,signature 为接收到的签名,并使用 params 作为 EC 域参数,以 Q 作为公钥。

    否则,key[[algorithm]] 内部槽的 namedCurve 属性为适用规范中指定的值

    执行该规范中指定的 ECDSA 验证步骤,传入 MsignatureparamsQ,并得出所声称的签名是否有效的指示。

  7. result 为一个布尔值,如果签名有效则为 true,否则为 false

  8. 返回 result

23.7.3 生成密钥

  1. 如果 usages 包含一个不是“sign”或“verify”的值,则抛出一个 SyntaxError

  2. 如果 normalizedAlgorithmnamedCurve 成员为“P-256”、“P-384”或“P-521

    生成一个椭圆曲线密钥对(如 [RFC6090] 中定义),其域参数用于 normalizedAlgorithmnamedCurve 成员标识的曲线。

    如果 normalizedAlgorithmnamedCurve 成员为适用规范中指定的值

    执行该规范中指定的 ECDSA 生成步骤,传入 normalizedAlgorithm,并得出椭圆曲线密钥对。

    否则

    抛出一个 NotSupportedError

  3. 如果执行密钥生成操作导致错误,则抛出一个 OperationError

  4. algorithm 为一个新的 EcKeyAlgorithm 对象。

  5. algorithmname 属性设置为“ECDSA”。

  6. algorithmnamedCurve 属性设置为等于 normalizedAlgorithmnamedCurve 成员。

  7. publicKey 为表示所生成密钥对的公钥的新 CryptoKey

  8. publicKey[[type]] 内部槽设置为“public

  9. publicKey[[algorithm]] 内部槽设置为 algorithm

  10. publicKey[[extractable]] 内部槽设置为 true。

  11. publicKey[[usages]] 内部槽设置为 usages[ "verify" ]用法交集

  12. privateKey 为表示所生成密钥对的私钥的新 CryptoKey

  13. privateKey[[type]] 内部槽设置为“private

  14. privateKey[[algorithm]] 内部槽设置为 algorithm

  15. privateKey[[extractable]] 内部槽设置为 extractable

  16. privateKey[[usages]] 内部槽设置为 usages[ "sign" ]用法交集

  17. result 为一个新的 CryptoKeyPair 字典。

  18. resultpublicKey 属性设置为 publicKey

  19. resultprivateKey 属性设置为 privateKey

  20. 返回 result

23.7.4 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 是“spki
    1. 如果 usages 包含一个不是“verify”的值,则抛出一个 SyntaxError

    2. spki 为对 keyData 运行解析 subjectPublicKeyInfo 算法的结果

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段不等于 [RFC5480] 中定义的 id-ecPublicKey 对象标识符,则抛出一个 DataError

    5. 如果 spkialgorithm AlgorithmIdentifier 字段的 parameters 字段不存在,则抛出一个 DataError

    6. paramsspkialgorithm AlgorithmIdentifier 字段的 parameters 字段。

    7. 如果 params 不是 [RFC5480] 中定义的指定 namedCurveECParameters ASN.1 类型的实例,则抛出一个 DataError

    8. namedCurve 为一个字符串,其初始值为 undefined。

    9. 如果 params 等同于 [RFC5480] 中定义的 secp256r1 对象标识符

      namedCurve 设置为“P-256”。

      如果 params 等同于 [RFC5480] 中定义的 secp384r1 对象标识符

      namedCurve 设置为“P-384”。

      如果 params 等同于 [RFC5480] 中定义的 secp521r1 对象标识符

      namedCurve 设置为“P-521”。

    10. 如果 namedCurve 不为 undefined
      1. publicKey 为通过执行 [SEC1] 第 2.3.4 节中定义的转换步骤(使用 spkisubjectPublicKey 字段)所标识的椭圆曲线公钥。

        非压缩点格式 必须 被支持。

      2. 如果实现不支持压缩点格式且提供了压缩点,则抛出一个 DataError

      3. 如果发生解码错误或发现标识点,则抛出一个 DataError

      4. key 为一个表示 publicKey 的新 CryptoKey

      否则
      1. 执行由其他适用规范定义的任何密钥导入步骤,传入 formatspki,并获取 namedCurvekey

      2. 如果发生错误或没有适用规范,则抛出一个 DataError

    11. 如果 namedCurve 已定义,且不等于 normalizedAlgorithmnamedCurve 成员,则抛出一个 DataError

    12. 如果公钥值不是 normalizedAlgorithmnamedCurve 成员标识的椭圆曲线上的有效点,则抛出一个 DataError

    13. key[[type]] 内部槽设置为“public

    14. algorithm 为一个新的 EcKeyAlgorithm

    15. algorithmname 属性设置为“ECDSA”。

    16. algorithmnamedCurve 属性设置为 namedCurve

    17. key[[algorithm]] 内部槽设置为 algorithm

    如果 format 是“pkcs8
    1. 如果 usages 包含一个不是“sign”的值,则抛出一个 SyntaxError

    2. privateKeyInfo 为对 keyData 运行解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则抛出一个 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC5480] 中定义的 id-ecPublicKey 对象标识符,则抛出一个 DataError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段不存在,则抛出一个 DataError

    6. paramsprivateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段。

    7. 如果 params 不是 [RFC5480] 中定义的指定 namedCurveECParameters ASN.1 类型的实例,则抛出一个 DataError

    8. namedCurve 为一个字符串,其初始值为 undefined。

    9. 如果 params 等同于 [RFC5480] 中定义的 secp256r1 对象标识符

      namedCurve 设置为“P-256”。

      如果 params 等同于 [RFC5480] 中定义的 secp384r1 对象标识符

      namedCurve 设置为“P-384”。

      如果 params 等同于 [RFC5480] 中定义的 secp521r1 对象标识符

      namedCurve 设置为“P-521”。

    10. 如果 namedCurve 不为 undefined
      1. ecPrivateKey 为执行解析 ASN.1 结构算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC5915] 第 3 节中指定的 ASN.1 ECPrivateKey 结构,并将 exactData 设置为 true。

      2. 如果解析时发生错误,则 抛出 DataError

      3. 如果 ecPrivateKeyparameters 字段存在,且不是 [RFC5480] 中定义的 namedCurve ASN.1 类型的实例,或者未包含与 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段相同的对象标识符,则抛出一个 DataError

      4. key 为一个表示通过执行 [RFC5915] 第 3 节中定义的转换步骤(使用 ecPrivateKey)所标识的椭圆曲线私钥的新 CryptoKey

      否则
      1. 执行由其他适用规范定义的任何密钥导入步骤,传入 formatprivateKeyInfo,并获取 namedCurvekey

      2. 如果发生错误或没有适用规范,则抛出一个 DataError

    11. 如果 namedCurve 已定义,且不等于 normalizedAlgorithmnamedCurve 成员,则抛出一个 DataError

    12. 如果私钥值不是 normalizedAlgorithmnamedCurve 成员标识的椭圆曲线上的有效点,则抛出一个 DataError

    13. key[[type]] 内部槽设置为“private

    14. algorithm 为一个新的 EcKeyAlgorithm

    15. algorithmname 属性设置为“ECDSA”。

    16. algorithmnamedCurve 属性设置为 namedCurve

    17. key[[algorithm]] 内部槽设置为 algorithm

    如果 format 是“jwk
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果存在 d 字段且 usages 包含一个不是“sign”的值,或者,如果不存在 d 字段且 usages 包含一个不是“verify”的值,则抛出一个 SyntaxError

    3. 如果 jwkkty 字段不是“EC”,则抛出一个 DataError

    4. 如果 usages 非空,且 jwk 中存在 use 字段,但该字段不是“sig”,则抛出一个 DataError

    5. 如果 jwk 中存在 key_ops 字段,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    6. 如果 jwk 中存在 ext 字段且其值为 false,同时 extractable 为 true,则抛出一个 DataError

    7. namedCurve 为一个值等于 jwkcrv 字段的字符串。

    8. 如果 namedCurve 不等于 normalizedAlgorithmnamedCurve 成员,则抛出一个 DataError

    9. 如果 namedCurve 等于“P-256”、“P-384”或“P-521
      1. algNamedCurve 为一个初始值为 undefined 的字符串。

      2. 如果 alg 字段不存在
        algNamedCurve 为 undefined。
        如果 alg 字段等于字符串“ES256”
        algNamedCurve 为字符串“P-256”。
        如果 alg 字段等于字符串“ES384”
        algNamedCurve 为字符串“P-384”。
        如果 alg 字段等于字符串“ES512”
        algNamedCurve 为字符串“P-521”。
        否则
        抛出 DataError
      3. 如果 algNamedCurve 已定义,且不等于 namedCurve,则抛出一个 DataError

      4. 如果存在 d 字段
        1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.2.2 节的要求,则抛出一个 DataError

        2. key 为一个新的 CryptoKey 对象,该对象表示通过根据 JSON Web Algorithms [JWA] 第 6.2.2 节解释 jwk 所标识的椭圆曲线私钥。

        3. Key[[type]] 内部槽设置为“private”。

        否则
        1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.2.1 节的要求,则抛出一个 DataError

        2. key 为一个新的 CryptoKey 对象,该对象表示通过根据 JSON Web Algorithms [JWA] 第 6.2.1 节解释 jwk 所标识的椭圆曲线公钥。

        3. Key[[type]] 内部槽设置为“public”。

      否则
      1. 执行由其他适用规范定义的任何密钥导入步骤,传入 formatjwk,并获取 key

      2. 如果发生错误或没有适用规范,则抛出一个 DataError

    10. 如果键值不是 normalizedAlgorithmnamedCurve 成员所标识的椭圆曲线上的有效点,则 抛出 一个 DataError

    11. algorithmEcKeyAlgorithm 对象的一个新实例。

    12. algorithmname 属性设置为 "ECDSA"。

    13. algorithmnamedCurve 属性设置为 namedCurve

    14. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "raw"
    1. 如果 normalizedAlgorithmnamedCurve 成员不是一个 命名曲线,则 抛出 一个 DataError

    2. 如果 usages 包含一个不是“verify”的值,则抛出一个 SyntaxError

    3. 如果 namedCurve 为 "P-256"、"P-384" 或 "P-521"
      1. Q 为通过对 keyData 执行 [SEC1] 第 2.3.4 节中定义的转换步骤,在 normalizedAlgorithmnamedCurve 成员所标识的曲线上得到的椭圆曲线点。

        非压缩点格式 必须 被支持。

      2. 如果实现不支持压缩点格式且提供了压缩点,则抛出一个 DataError

      3. 如果发生解码错误或发现标识点,则抛出一个 DataError

      4. key 为一个代表 Q 的新 CryptoKey

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatkeyData 并获取 key

      2. 如果发生错误或没有 适用规范,则 抛出 一个 DataError

    4. algorithm 为一个新的 EcKeyAlgorithm 对象。

    5. algorithmname 属性设置为 "ECDSA"。

    6. algorithmnamedCurve 属性设置为等于 normalizedAlgorithmnamedCurve 成员。

    7. key[[type]] 内部槽位设置为 "public"

    8. key[[algorithm]] 内部槽位设置为 algorithm

    否则

    抛出 NotSupportedError

  3. 返回 key

23.7.5 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问由 key[[handle]] 内部槽位所代表的底层加密密钥材料,则 抛出 一个 OperationError

  3. 如果 format 为 "spki"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC5480] 中定义的 OID id-ecPublicKey

        • parameters 字段设置为 [RFC5480] 中定义的 ECParameters ASN.1 类型的一个实例,如下所示:

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

          keyData 为代表椭圆曲线公钥的 字节序列,该公钥由 key[[handle]] 内部槽位根据 [RFC5480] 第 2.2 节中指定的编码规则并使用未压缩形式表示,以及 keyData

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp256r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp384r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp521r1

          否则
          1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurveOidkeyData

          2. parameters 设置为 namedCurve 选择,其值等于对象标识符 namedCurveOid

      • subjectPublicKey 字段设置为 keyData

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "pkcs8"
    1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC5480] 中定义的 OID id-ecPublicKey

        • parameters 字段设置为 [RFC5480] 中定义的 ECParameters ASN.1 类型的一个实例,如下所示:

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

          keyData 为对 [RFC5915] 第 3 节中定义的 ECPrivateKey 结构实例进行 DER 编码的结果,该结构对应由 key[[handle]] 内部槽位所代表的椭圆曲线私钥,并且符合以下条件:

          • 存在 parameters 字段,且等同于此 PrivateKeyInfo ASN.1 结构的 privateKeyAlgorithm 字段的 parameters 字段。

          • 存在 publicKey 字段,并代表与由 key[[handle]] 内部槽位所代表的椭圆曲线私钥相关联的椭圆曲线公钥。

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp256r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp384r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp521r1

          否则
          1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurveOidkeyData

          2. parameters 设置为 namedCurve 选择,其值等于对象标识符 namedCurveOid

      • privateKey 字段设置为 keyData

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为 "EC"。

    3. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"
      1. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"
        jwkcrv 属性设置为 "P-256"
        如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"
        jwkcrv 属性设置为 "P-384"
        如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"
        jwkcrv 属性设置为 "P-521"
      2. 根据 JSON Web 算法 [JWA] 第 6.2.1.2 节中的定义,设置 jwkx 属性。

      3. 根据 JSON Web 算法 [JWA] 第 6.2.1.3 节中的定义,设置 jwky 属性。

      4. 如果 key[[type]] 内部槽位为 "private"

        根据 JSON Web 算法 [JWA] 第 6.2.2.1 节中的定义,设置 jwkd 属性。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurve 和一个新的 jwk 值。

      2. jwkcrv 属性设置为 namedCurve

    4. jwkkey_ops 属性设置为 keyusages 属性。

    5. jwkext 属性设置为 key[[extractable]] 内部槽位。

    6. resultjwk

    如果 format 为 "raw"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

      data 为代表椭圆曲线点 Q字节序列,该点由 key[[handle]] 内部槽位根据 [SEC1] 2.3.3 使用未压缩格式表示。

      否则

      执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurvedata

    3. resultdata

    否则

    抛出 NotSupportedError

  4. 返回 result

24. ECDH

24.1 描述

本节是非规范性的。

这描述了使用椭圆曲线迪菲-赫尔曼(ECDH)进行密钥生成和密钥协商,正如 [RFC6090] 所指定的那样。

其他规范 可能会指定将其他椭圆曲线与 ECDH 一起使用。要指定额外的椭圆曲线,规范必须定义 曲线名称ECDH 生成步骤ECDH 推导步骤ECDH 密钥导入步骤ECDH 密钥导出步骤

24.2 注册

该算法的 识别算法名称 为 "ECDH"。

操作 参数 结果
generateKey(生成密钥) EcKeyGenParams CryptoKeyPair
deriveBits(派生比特) EcdhKeyDeriveParams byte sequence (字节序列)
importKey(导入密钥) EcKeyImportParams CryptoKey
exportKey(导出密钥) object

24.3 EcdhKeyDeriveParams 字典

WebIDLdictionary EcdhKeyDeriveParams : Algorithm {
  required CryptoKey public;
};

public 成员代表对方的 EC 公钥。

24.4 操作

24.4.1 生成密钥

  1. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

  2. 如果 normalizedAlgorithmnamedCurve 成员为 "P-256"、"P-384" 或 "P-521"

    生成一个椭圆曲线密钥对,正如 [RFC6090] 中所定义,使用 normalizedAlgorithmnamedCurve 成员所标识曲线的域参数。

    如果 normalizedAlgorithmnamedCurve 成员是 适用规范 中指定的值,该规范指定了该值与 ECDH 的使用

    执行该规范中指定的 ECDH 生成步骤,传入 normalizedAlgorithm,并得到一个椭圆曲线密钥对。

    否则

    抛出一个 NotSupportedError

  3. 如果执行操作导致错误,则 抛出 一个 OperationError

  4. algorithm 为一个新的 EcKeyAlgorithm 对象。

  5. algorithmname 成员设置为 "ECDH"。

  6. algorithmnamedCurve 属性设置为等于 normalizedAlgorithmnamedCurve 成员。

  7. publicKey 为一个新的 CryptoKey,代表所生成密钥对的公钥。

  8. publicKey[[type]] 内部槽位设置为 "public"

  9. publicKey[[algorithm]] 内部槽位设置为 algorithm

  10. publicKey[[extractable]] 内部槽位设置为 true。

  11. publicKey[[usages]] 内部槽位设置为一个空列表。

  12. privateKey 为一个新的 CryptoKey,代表所生成密钥对的私钥。

  13. privateKey[[type]] 内部槽位设置为 "private"

  14. privateKey[[algorithm]] 内部槽位设置为 algorithm

  15. privateKey[[extractable]] 内部槽位设置为 extractable

  16. privateKey[[usages]] 内部槽位设置为 usages[ "deriveKey", "deriveBits" ]用法交集

  17. result 为一个新的 CryptoKeyPair 字典。

  18. resultpublicKey 属性设置为 publicKey

  19. resultprivateKey 属性设置为 privateKey

  20. 返回 result

24.4.2 派生位 (Derive Bits)

  1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

  2. publicKeynormalizedAlgorithmpublic 成员。

  3. 如果 publicKey[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

  4. 如果 publicKey[[algorithm]] 内部槽位的 name 属性不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 一个 InvalidAccessError

  5. 如果 publicKey[[algorithm]] 内部槽位的 namedCurve 属性不等于 key[[algorithm]] 内部槽位的 namedCurve 属性,则 抛出 一个 InvalidAccessError

  6. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"
    1. 执行 [RFC6090] 第 4 节中指定的 ECDH 原语,使用 key 作为 EC 私钥 d,并使用由 publicKey[[handle]] 内部槽位所代表的 EC 公钥作为 EC 公钥。

    2. secret 为一个 字节序列,包含将 [RFC6090] 第 6.2 节中定义的域元素到八位组字符串的转换应用于 ECDH 原语输出的结果。

    如果 key[[algorithm]] 内部槽位的 namedCurve 属性是 适用规范 中指定的值,该规范指定了该值与 ECDH 的使用

    执行该规范中指定的 ECDH 推导步骤,传入 keypublicKey,并得到 secret

    否则

    抛出一个 NotSupportedError

  7. 如果执行操作导致错误,则 抛出 一个 OperationError

  8. 如果 length 为 null
    返回 secret
    否则
    如果 secret比特长度 小于 length
    抛出 一个 OperationError
    否则
    返回一个 包含 secretlength 比特的 字节序列

24.4.3 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 "spki"
    1. 如果 usages 不为空,则 抛出 一个 SyntaxError

    2. spki 为对 keyData 运行 解析 SubjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段不等于 [RFC5480] 中定义的 id-ecPublicKey 对象标识符,则抛出一个 DataError

    5. 如果 spkialgorithm AlgorithmIdentifier 字段的 parameters 字段不存在,则抛出一个 DataError

    6. paramsspkialgorithm AlgorithmIdentifier 字段的 parameters 字段。

    7. 如果 params 不是 [RFC5480] 中定义的指定 namedCurveECParameters ASN.1 类型的实例,则抛出一个 DataError

    8. namedCurve 为一个字符串,其初始值为 undefined。

    9. 如果 params 等同于 [RFC5480] 中定义的 secp256r1 对象标识符

      namedCurve 设置为“P-256”。

      如果 params 等同于 [RFC5480] 中定义的 secp384r1 对象标识符

      namedCurve 设置为“P-384”。

      如果 params 等同于 [RFC5480] 中定义的 secp521r1 对象标识符

      namedCurve 设置为“P-521”。

    10. 如果 namedCurve 不为 undefined
      1. publicKey 为通过对 spkisubjectPublicKey 字段执行 [SEC1] 第 2.3.4 节中定义的转换步骤所标识的椭圆曲线公钥。

        非压缩点格式 必须 被支持。

      2. 如果实现不支持压缩点格式且提供了压缩点,则抛出一个 DataError

      3. 如果发生解码错误或发现标识点,则抛出一个 DataError

      4. key 为一个代表 publicKey 的新 CryptoKey

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatspki 并获取 namedCurvekey

      2. 如果发生错误或没有 适用规范,则 抛出 一个 DataError

    11. 如果定义了 namedCurve,且不等于 normalizedAlgorithmnamedCurve 成员,则 抛出 一个 DataError

    12. 如果键值不是 normalizedAlgorithmnamedCurve 成员所标识的椭圆曲线上的有效点,则 抛出 一个 DataError

    13. key[[type]] 内部槽位设置为 "public"

    14. algorithm 为一个新的 EcKeyAlgorithm

    15. algorithmname 属性设置为 "ECDH"。

    16. algorithmnamedCurve 属性设置为 namedCurve

    17. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "pkcs8"
    1. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

    2. privateKeyInfo 为对 keyData 运行 解析 PrivateKeyInfo 算法的结果。

    3. 如果解析过程中发生错误,则 抛出 一个 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm 字段中的算法对象标识符字段不等于 [RFC5480] 中定义的 id-ecPublicKey 对象标识符,则 抛出 一个 DataError

    5. 如果 privateKeyInfoprivateKeyAlgorithm 字段中的 parameters 字段不存在,则 抛出 一个 DataError

    6. paramsprivateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段。

    7. 如果 params 不是 [RFC5480] 中定义的指定 namedCurveECParameters ASN.1 类型的实例,则抛出一个 DataError

    8. namedCurve 为一个字符串,其初始值为 undefined。

    9. 如果 params 等同于 [RFC5480] 中定义的 secp256r1 对象标识符

      namedCurve 设置为 "P-256"。

      如果 params 等同于 [RFC5480] 中定义的 secp384r1 对象标识符

      namedCurve 设置为 "P-384"。

      如果 params 等同于 [RFC5480] 中定义的 secp521r1 对象标识符

      namedCurve 设置为 "P-521"。

    10. 如果 namedCurve 不为 undefined
      1. ecPrivateKey 为执行 解析 ASN.1 结构 算法的结果,将 privateKeyInfoprivateKey 字段作为 data,将 [RFC5915] 第 3 节中指定的 ASN.1 ECPrivateKey 结构作为 structure,并设置 exactData 为 true。

      2. 如果解析时发生错误,则 抛出 DataError

      3. 如果 ecPrivateKeyparameters 字段存在,且不是 [RFC5480] 中定义的 namedCurve ASN.1 类型的一个实例,或者不包含与 privateKeyInfoprivateKeyAlgorithm 字段中的 parameters 字段相同的对象标识符,则 抛出 一个 DataError

      4. key 为一个新的 CryptoKey,代表通过对 ecPrivateKey 使用 [RFC5915] 第 3 节中定义的转换步骤所标识的椭圆曲线私钥。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatprivateKeyInfo 并获取 namedCurvekey

      2. 如果发生错误或没有 适用规范,则 抛出 一个 DataError

    11. 如果定义了 namedCurve,且不等于 normalizedAlgorithmnamedCurve 成员,则 抛出 一个 DataError

    12. 如果键值不是 normalizedAlgorithmnamedCurve 成员所标识的椭圆曲线上的有效点,则 抛出 一个 DataError

    13. key[[type]] 内部槽位设置为 "private"。

    14. algorithm 为一个新的 EcKeyAlgorithm

    15. algorithmname 属性设置为 "ECDH"。

    16. algorithmnamedCurve 属性设置为 namedCurve

    17. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果存在 d 字段,且 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

    3. 如果不存在 d 字段,且 usages 不为空,则 抛出 一个 SyntaxError

    4. 如果 jwkkty 字段不是 "EC",则 抛出 一个 DataError

    5. 如果 usages 非空,且 jwkuse 字段存在且不等于 "enc",则 抛出 一个 DataError

    6. 如果 jwkkey_ops 字段存在,且根据 JSON Web 密钥 [JWK] 的要求是无效的,或者它不包含所有指定的 usages 值,则 抛出 一个 DataError

    7. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 一个 DataError

    8. namedCurve 为一个字符串,其值等于 jwkcrv 字段。

    9. 如果 namedCurve 不等于 normalizedAlgorithmnamedCurve 成员,则 抛出 一个 DataError

    10. 如果 namedCurve 为 "P-256"、"P-384" 或 "P-521"
      如果 d 字段存在
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.2.2 节的要求,则抛出一个 DataError

      2. key 为一个新的 CryptoKey 对象,代表通过根据 JSON Web 算法 [JWA] 第 6.2.2 节解释 jwk 所标识的椭圆曲线私钥。

      3. Key[[type]] 内部槽位设置为 "private"。

      否则
      1. 如果 jwk 不满足 JSON Web Algorithms [JWA] 第 6.2.1 节的要求,则抛出一个 DataError

      2. key 为一个新的 CryptoKey 对象,代表通过根据 JSON Web 算法 [JWA] 第 6.2.1 节解释 jwk 所标识的椭圆曲线公钥。

      3. Key[[type]] 内部槽位设置为 "public"。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatjwk 并获取 key

      2. 如果发生错误或没有 适用规范,则 抛出 一个 DataError

    11. 如果键值不是 normalizedAlgorithmnamedCurve 成员所标识的椭圆曲线上的有效点,则 抛出 一个 DataError

    12. algorithmEcKeyAlgorithm 对象的一个新实例。

    13. algorithmname 属性设置为 "ECDH"。

    14. algorithmnamedCurve 属性设置为 namedCurve

    15. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "raw"
    1. 如果 normalizedAlgorithmnamedCurve 成员不是一个 命名曲线,则 抛出 一个 DataError

    2. 如果 usages 不是空列表,则 抛出 一个 SyntaxError

    3. 如果 namedCurve 为 "P-256"、"P-384" 或 "P-521"
      1. Q 为通过对 keyData 执行 [SEC1] 第 2.3.4 节中定义的转换步骤,在 normalizedAlgorithmnamedCurve 成员所标识的曲线上得到的椭圆曲线公钥。

        非压缩点格式 必须 被支持。

      2. 如果实现不支持压缩点格式且提供了压缩点,则抛出一个 DataError

      3. 如果发生解码错误或发现标识点,则抛出一个 DataError

      4. key 为一个代表 Q 的新 CryptoKey

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导入步骤,传入 formatkeyData 并获取 key

      2. 如果发生错误或没有 适用规范,则 抛出 一个 DataError

    4. algorithmEcKeyAlgorithm 对象的一个新实例。

    5. algorithmname 属性设置为 "ECDH"。

    6. algorithmnamedCurve 属性设置为等于 normalizedAlgorithmnamedCurve 成员。

    7. key[[type]] 内部槽位设置为 "public"

    8. key[[algorithm]] 内部槽位设置为 algorithm

  3. 返回 key

24.4.4 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问由 key[[handle]] 内部槽位所代表的底层加密密钥材料,则 抛出 一个 OperationError

  3. 如果 format 为 "spki"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC5480] 中定义的 OID id-ecPublicKey

        • parameters 字段设置为 [RFC5480] 中定义的 ECParameters ASN.1 类型的一个实例,如下所示:

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

          keyData 为代表椭圆曲线公钥的 字节序列,该公钥由 key[[handle]] 内部槽位根据 [SEC1] 第 2.3.3 节中指定的编码规则并使用未压缩形式表示。

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp256r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp384r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp521r1

          否则
          1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurveOidkeyData

          2. parameters 设置为 namedCurve 选择,其值等于对象标识符 namedCurveOid

      • subjectPublicKey 字段设置为 keyData

    如果 format 为 "pkcs8"
    1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 字段设置为 [RFC5480] 中定义的 OID id-ecPublicKey

        • parameters 字段设置为 [RFC5480] 中定义的 ECParameters ASN.1 类型的一个实例,如下所示:

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

          keyData 为对 [RFC5915] 第 3 节中定义的 ECPrivateKey 结构实例进行 DER 编码的结果,该结构对应由 key[[handle]] 内部槽位所代表的椭圆曲线私钥,并且符合以下条件:

          • 存在 parameters 字段,且等同于此 PrivateKeyInfo ASN.1 结构的 privateKeyAlgorithm 字段的 parameters 字段。

          • 存在 publicKey 字段,并代表与由 key[[handle]] 内部槽位所代表的椭圆曲线私钥相关联的椭圆曲线公钥。

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp256r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp384r1

          如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"

          parameters 设置为 namedCurve 选择,其值等于 [RFC5480] 中定义的对象标识符 secp521r1

          否则
          1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurveOidkeyData

          2. parameters 设置为 namedCurve 选择,其值等于对象标识符 namedCurveOid

      • privateKey 字段设置为 keyData

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为 "EC"。

    3. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"
      1. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"
        jwkcrv 属性设置为 "P-256"
        如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-384"
        jwkcrv 属性设置为 "P-384"
        如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-521"
        jwkcrv 属性设置为 "P-521"
      2. 根据 JSON Web 算法 [JWA] 第 6.2.1.2 节中的定义,设置 jwkx 属性。

      3. 根据 JSON Web 算法 [JWA] 第 6.2.1.3 节中的定义,设置 jwky 属性。

      4. 如果 key[[type]] 内部槽位为 "private"

        根据 JSON Web 算法 [JWA] 第 6.2.2.1 节中的定义,设置 jwkd 属性。

      否则
      1. 执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurve 和一个新的 jwk 值。

      2. jwkcrv 属性设置为 namedCurve

    4. jwkkey_ops 属性设置为 keyusages 属性。

    5. jwkext 属性设置为 key[[extractable]] 内部槽位。

    6. resultjwk

    如果 format 为 "raw"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. 如果 key[[algorithm]] 内部槽位的 namedCurve 属性为 "P-256"、"P-384" 或 "P-521"

      data 为代表椭圆曲线公钥的 字节序列,该公钥由 key[[handle]] 内部槽位根据 [SEC1] 第 2.3.3 节中指定的编码规则并使用未压缩形式表示。

      否则

      执行由 其他适用规范 定义的任何 密钥导出步骤,传入 formatkey[[algorithm]] 内部槽位的 namedCurve 属性,并获取 namedCurvedata

    3. resultdata

  4. 返回 result

25. Ed25519

25.1 描述

本节是非规范性的。

"Ed25519" 算法标识符用于使用 [RFC8032] 中指定的 Ed25519 算法执行签名和验证。

25.2 注册

该算法的 识别算法名称 为 "Ed25519"。

操作 参数 结果
符号 byte sequence (字节序列)
verify(验证) boolean
generateKey(生成密钥) CryptoKeyPair
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object

25.3 操作

25.3.1 签名

  1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

  2. result 为执行 Ed25519 签名过程的结果,该过程如 [RFC8032] 第 5.1.6 节所指定,以 message 作为 M,并使用与 key 相关联的 Ed25519 私钥。

    Issue 1

    某些实现可能(希望)根据 draft-irtf-cfrg-det-sigs-with-noise 生成随机签名,而不是根据 [RFC8032] 生成确定性签名。

    参见 WICG/webcrypto-secure-curves 问题 28

  3. 返回 result

25.3.2 验证

  1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

  2. 如果 key 的键数据代表 Ed25519 椭圆曲线上的无效点或小阶元素,则返回 false

    Issue 2

    并非所有实现都执行此检查。

    参见 WICG/webcrypto-secure-curves 问题 27

  3. 如果编码在 signature 前半部分的点 R 代表 Ed25519 椭圆曲线上的无效点或小阶元素,则返回 false

    问题 3

    并非所有实现都执行此检查。

    参见 WICG/webcrypto-secure-curves 问题 27

  4. 执行 Ed25519 验证步骤,如 [RFC8032] 第 5.1.7 节所指定,使用无辅因子(未批处理)方程 [S]B = R + [k]A',应用于 signature,以 message 作为 M,并使用与 key 相关联的 Ed25519 公钥。

  5. result 为一个布尔值,如果签名有效则为 true,否则为 false

  6. 返回 result

25.3.3 生成密钥

  1. 如果 usages 包含一个不是“sign”或“verify”的值,则抛出一个 SyntaxError

  2. 生成一个 Ed25519 密钥对,如 [RFC8032] 第 5.1.5 节所定义。

  3. algorithm 为一个新的 KeyAlgorithm 对象。

  4. algorithmname 属性设置为 "Ed25519"。

  5. publicKey 为一个新的 CryptoKey,代表所生成密钥对的公钥。

  6. publicKey[[type]] 内部槽位设置为 "public"

  7. publicKey[[algorithm]] 内部槽位设置为 algorithm

  8. publicKey[[extractable]] 内部槽位设置为 true。

  9. publicKey[[usages]] 内部槽位设置为 usages[ "verify" ]用法交集

  10. privateKey 为一个新的 CryptoKey,代表所生成密钥对的私钥。

  11. privateKey[[type]] 内部槽位设置为 "private"

  12. privateKey[[algorithm]] 内部槽位设置为 algorithm

  13. privateKey[[extractable]] 内部槽位设置为 extractable

  14. privateKey[[usages]] 内部槽位设置为 usages[ "sign" ]用法交集

  15. result 为一个新的 CryptoKeyPair 字典。

  16. resultpublicKey 属性设置为 publicKey

  17. resultprivateKey 属性设置为 privateKey

  18. 返回 result

25.3.4 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 "spki"
    1. 如果 usages 包含一个不是“verify”的值,则抛出一个 SyntaxError

    2. spki 为对 keyData 运行 解析 subjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm 字段中的 algorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段不等于 [RFC8410] 中定义的 id-Ed25519 对象标识符,则 抛出 一个 DataError

    5. 如果 spkialgorithm 字段中的 algorithm AlgorithmIdentifier 字段的 parameters 字段存在,则 抛出 一个 DataError

    6. publicKeyspkisubjectPublicKey 字段标识的 Ed25519 公钥。

    7. key 为表示 publicKey 的新 CryptoKey

    8. key[[type]] 内部槽位设置为 "public"

    9. algorithm 为一个新的 KeyAlgorithm

    10. algorithmname 属性设置为 "Ed25519"。

    11. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "pkcs8"
    1. 如果 usages 包含一个不是“sign”的值,则抛出一个 SyntaxError

    2. privateKeyInfo 为对 keyData 运行 解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则抛出一个 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC8410] 中定义的 id-Ed25519 对象标识符,则 抛出 一个 DataError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段存在,则 抛出 一个 DataError

    6. curvePrivateKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC8410] 第 7 节中指定的 ASN.1 CurvePrivateKey 结构,并将 exactData 设置为 true。

    7. 如果解析时发生错误,则 抛出 DataError

    8. key 为表示 curvePrivateKey 标识的 Ed25519 私钥的新 CryptoKey

    9. key[[type]] 内部槽位设置为 "private"

    10. algorithm 为一个新的 KeyAlgorithm

    11. algorithmname 属性设置为 "Ed25519"。

    12. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 d 字段存在且 usages 包含一个不是 "sign" 的值,或者如果 d 字段不存在且 usages 包含一个不是 "verify" 的值,则 抛出 一个 SyntaxError

    3. 如果 jwkkty 字段不是 "OKP",则 抛出 一个 DataError

    4. 如果 jwkcrv 字段不是 "Ed25519",则 抛出 一个 DataError

    5. 如果 jwkalg 字段存在且不是 "Ed25519" 或 "EdDSA",则 抛出 一个 DataError

    6. 如果 usages 非空且 jwkuse 字段存在且不是 "sig",则 抛出 一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效,或者它不包含所有指定的 usages 值,则 抛出 一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 一个 DataError

    9. 如果 d 字段存在
      1. 如果 jwk 不符合 [RFC8037] 第 2 节中描述的 JWK 私钥格式要求,则 抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过按照 [RFC8037] 第 2 节解释 jwk 所确定的 Ed25519 私钥。

      3. Key[[type]] 内部槽位设置为 "private"。

      否则
      1. 如果 jwk 不符合 [RFC8037] 第 2 节中描述的 JWK 公钥格式要求,则 抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过按照 [RFC8037] 第 2 节解释 jwk 所确定的 Ed25519 公钥。

      3. Key[[type]] 内部槽位设置为 "public"。

    10. algorithmKeyAlgorithm 对象的一个新实例。

    11. algorithmname 属性设置为 "Ed25519"。

    12. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "raw"
    1. 如果 usages 包含一个不是“verify”的值,则抛出一个 SyntaxError

    2. algorithm 为一个新的 KeyAlgorithm 对象。

    3. algorithmname 属性设置为 "Ed25519"。

    4. key 为一个表示 keyData 中提供的密钥数据的新 CryptoKey

    5. key[[type]] 内部槽位设置为 "public"

    6. key[[algorithm]] 内部槽位设置为 algorithm

    否则

    抛出 NotSupportedError

  3. 返回 key

25.3.5 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问由 key[[handle]] 内部槽位表示的底层加密密钥材料,则 抛出 一个 OperationError

  3. 如果 format 为 "spki"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 对象标识符设置为 [RFC8410] 中定义的 id-Ed25519 OID。

      • subjectPublicKey 字段设置为 keyData

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "pkcs8"
    1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 对象标识符设置为 [RFC8410] 中定义的 id-Ed25519 OID。

      • privateKey 字段设置为 DER 编码 [RFC8410] 第 7 节中定义的 CurvePrivateKey ASN.1 类型的结果,该类型表示由 key[[handle]] 内部槽位表示的 Ed25519 私钥。

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为 "OKP"。

    3. jwkalg 属性设置为 "Ed25519"。

    4. jwkcrv 属性设置为 "Ed25519"。

    5. 根据 [RFC8037] 第 2 节中的定义,设置 jwkx 属性。

    6. 如果 key[[type]] 内部槽位是 "private"
      根据 [RFC8037] 第 2 节中的定义,设置 jwkd 属性。
    7. jwkkey_ops 属性设置为 keyusages 属性。

    8. jwkext 属性设置为 key[[extractable]] 内部槽位。

    9. resultjwk

    如果 format 为 "raw"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为表示由 key[[handle]] 内部槽位所表示的 Ed25519 公钥的 字节序列

    3. resultdata

    否则

    抛出 NotSupportedError

  4. 返回 result

26. X25519

26.1 描述

本节是非规范性的。

"X25519" 算法标识符用于使用 [RFC7748] 中指定的 X25519 算法执行密钥协商。

26.2 注册

此算法的 可识别算法名称 是 "X25519"。

操作 参数 结果
deriveBits(派生比特) EcdhKeyDeriveParams byte sequence (字节序列)
generateKey(生成密钥) CryptoKeyPair
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object

26.3 操作

26.3.1 派生位

  1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

  2. publicKeynormalizedAlgorithmpublic 成员。

  3. 如果 publicKey[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

  4. 如果 publicKey[[algorithm]] 内部槽位的 name 属性不等于 key[[algorithm]] 内部槽位的 name 属性,则 抛出 一个 InvalidAccessError

  5. secret 为执行 [RFC7748] 第 5 节中指定的 X25519 函数的结果,其中 key 作为 X25519 私钥 k,由 publicKey[[handle]] 内部槽位表示的 X25519 公钥作为 X25519 公钥 u

  6. 如果 secret 是全零值,则 抛出 一个 OperationError。根据 [RFC7748] 第 6.1 节,此检查必须在常数时间内执行。

  7. 如果 length 为 null
    返回 secret
    否则
    如果 secret 的长度(以位为单位)小于 length
    抛出 一个 OperationError
    否则
    返回一个 包含 secretlength 位的 字节序列

26.3.2 生成密钥

  1. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

  2. 生成一个 X25519 密钥对,私钥为 32 个随机字节,公钥为 [RFC7748] 第 6.1 节中定义的 X25519(a, 9)

  3. algorithm 为一个新的 KeyAlgorithm 对象。

  4. algorithmname 属性设置为 "X25519"。

  5. publicKey 为一个表示生成的密钥对的公钥的新 CryptoKey

  6. publicKey[[type]] 内部槽位设置为 "public"

  7. publicKey[[algorithm]] 内部槽位设置为 algorithm

  8. publicKey[[extractable]] 内部槽位设置为 true。

  9. publicKey[[usages]] 内部槽位设置为一个空列表。

  10. privateKey 为一个表示生成的密钥对的私钥的新 CryptoKey

  11. privateKey[[type]] 内部槽位设置为 "private"

  12. privateKey[[algorithm]] 内部槽位设置为 algorithm

  13. privateKey[[extractable]] 内部槽位设置为 extractable

  14. privateKey[[usages]] 内部槽位设置为 usages[ "deriveKey", "deriveBits" ]用法交集

  15. result 为一个新的 CryptoKeyPair 字典。

  16. resultpublicKey 属性设置为 publicKey

  17. resultprivateKey 属性设置为 privateKey

  18. 返回 result

26.3.3 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 "spki"
    1. 如果 usages 不为空,则 抛出 一个 SyntaxError

    2. spki 为对 keyData 运行 解析 subjectPublicKeyInfo 算法的结果。

    3. 如果解析时发生错误,则 抛出 DataError

    4. 如果 spkialgorithm 字段中的 algorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段不等于 [RFC8410] 中定义的 id-X25519 对象标识符,则 抛出 一个 DataError

    5. 如果 spkialgorithm 字段中的 algorithm AlgorithmIdentifier 字段的 parameters 字段存在,则 抛出 一个 DataError

    6. publicKeyspkisubjectPublicKey 字段标识的 X25519 公钥。

    7. key 为表示 publicKey 的新 CryptoKey

    8. key[[type]] 内部槽位设置为 "public"

    9. algorithm 为一个新的 KeyAlgorithm

    10. algorithmname 属性设置为 "X25519"。

    11. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "pkcs8"
    1. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

    2. privateKeyInfo 为对 keyData 运行 解析 privateKeyInfo 算法的结果。

    3. 如果解析时发生错误,则抛出一个 DataError

    4. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 [RFC8410] 中定义的 id-X25519 对象标识符,则 抛出 一个 DataError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段的 parameters 字段存在,则 抛出 一个 DataError

    6. curvePrivateKey 为执行 解析 ASN.1 结构 算法的结果,其中 dataprivateKeyInfoprivateKey 字段,structure 为 [RFC8410] 第 7 节中指定的 ASN.1 CurvePrivateKey 结构,并将 exactData 设置为 true。

    7. 如果解析时发生错误,则 抛出 DataError

    8. key 为表示 curvePrivateKey 标识的 X25519 私钥的新 CryptoKey

    9. key[[type]] 内部槽位设置为 "private"

    10. algorithm 为一个新的 KeyAlgorithm

    11. algorithmname 属性设置为 "X25519"。

    12. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 d 字段存在且 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的条目,则 抛出 一个 SyntaxError

    3. 如果 d 字段不存在且 usages 非空,则 抛出 一个 SyntaxError

    4. 如果 jwkkty 字段不是 "OKP",则 抛出 一个 DataError

    5. 如果 jwkcrv 字段不是 "X25519",则 抛出 一个 DataError

    6. 如果 usages 非空且 jwkuse 字段存在且不等于 "enc",则 抛出 一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效,或者它不包含所有指定的 usages 值,则 抛出 一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 一个 DataError

    9. 如果 d 字段存在
      1. 如果 jwk 不符合 [RFC8037] 第 2 节中描述的 JWK 私钥格式要求,则 抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过按照 [RFC8037] 第 2 节解释 jwk 所确定的 X25519 私钥。

      3. Key[[type]] 内部槽位设置为 "private"。

      否则
      1. 如果 jwk 不符合 [RFC8037] 第 2 节中描述的 JWK 公钥格式要求,则 抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过按照 [RFC8037] 第 2 节解释 jwk 所确定的 X25519 公钥。

      3. Key[[type]] 内部槽位设置为 "public"。

    10. algorithmKeyAlgorithm 对象的一个新实例。

    11. algorithmname 属性设置为 "X25519"。

    12. key[[algorithm]] 内部槽位设置为 algorithm

    如果 format 为 "raw"
    1. 如果 usages 不为空,则 抛出 一个 SyntaxError

    2. algorithm 为一个新的 KeyAlgorithm 对象。

    3. algorithmname 属性设置为 "X25519"。

    4. key 为一个表示 keyData 中提供的密钥数据的新 CryptoKey

    5. key[[type]] 内部槽位设置为 "public"

    6. key[[algorithm]] 内部槽位设置为 algorithm

    否则

    抛出 NotSupportedError

  3. 返回 key

26.3.4 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问由 key[[handle]] 内部槽位表示的底层加密密钥材料,则 抛出 一个 OperationError

  3. 如果 format 为 "spki"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5280] 中定义的 SubjectPublicKeyInfo ASN.1 结构的一个实例,具有以下属性

      • algorithm 字段设置为具有以下属性的 AlgorithmIdentifier ASN.1 类型

        • algorithm 对象标识符设置为 [RFC8410] 中定义的 id-X25519 OID。

      • subjectPublicKey 字段设置为 keyData

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "pkcs8"
    1. 如果 key[[type]] 内部槽位不是 "private",则 抛出 一个 InvalidAccessError

    2. data 为 [RFC5208] 中定义的 PrivateKeyInfo ASN.1 结构的一个实例,具有以下属性

      • version 字段设置为 0

      • privateKeyAlgorithm 字段设置为具有以下属性的 PrivateKeyAlgorithmIdentifier ASN.1 类型

        • algorithm 对象标识符设置为 [RFC8410] 中定义的 id-X25519 OID。

      • privateKey 字段设置为 DER 编码 [RFC8410] 第 7 节中定义的 CurvePrivateKey ASN.1 类型的结果,该类型表示由 key[[handle]] 内部槽位表示的 X25519 私钥。

    3. result 为对 data 进行 DER 编码的结果。

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为 "OKP"。

    3. jwkcrv 属性设置为 "X25519"。

    4. 根据 [RFC8037] 第 2 节中的定义,设置 jwkx 属性。

    5. 如果 key[[type]] 内部槽位是 "private"
      根据 [RFC8037] 第 2 节中的定义,设置 jwkd 属性。
    6. jwkkey_ops 属性设置为 keyusages 属性。

    7. jwkext 属性设置为 key[[extractable]] 内部槽位。

    8. resultjwk

    如果 format 为 "raw"
    1. 如果 key[[type]] 内部槽位不是 "public",则 抛出 一个 InvalidAccessError

    2. data 为表示由 key[[handle]] 内部槽位所表示的 X25519 公钥的 字节序列

    3. resultdata

    否则

    抛出 NotSupportedError

  4. 返回 result

27. AES-CTR

27.1 描述

本节是非规范性的。

"AES-CTR" 算法标识符用于使用 AES 在计数器模式下执行加密和解密,如 [NIST-SP800-38A] 中所述。

27.2 注册

此算法的 可识别算法名称 是 "AES-CTR"。

操作 参数 结果
encrypt(加密) AesCtrParams byte sequence (字节序列)
decrypt(解密) AesCtrParams byte sequence (字节序列)
generateKey(生成密钥) AesKeyGenParams CryptoKey
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object
get key length(获取密钥长度) AesDerivedKeyParams Integer

27.3 AesCtrParams 字典

WebIDLdictionary AesCtrParams : Algorithm {
  required BufferSource counter;
  required [EnforceRange] octet length;
};

counter 成员包含计数器块的初始值。counter 必须为 16 字节(AES 块大小)。计数器位是计数器块中最右侧的位。计数器块的其余部分用于随机数。计数器位使用 NIST SP 800-38A 附录 B.1 中指定的标准增量函数进行递增:计数器位被解释为一个大端整数并递增一。

length 成员包含递增的计数器块最右侧部分的长度(以位为单位)。

27.4 AesKeyAlgorithm 字典

WebIDLdictionary AesKeyAlgorithm : KeyAlgorithm {
  required unsigned short length;
};

length 成员表示密钥的长度(以位为单位)。

27.5 AesKeyGenParams 字典

WebIDLdictionary AesKeyGenParams : Algorithm {
  required [EnforceRange] unsigned short length;
};

length 成员表示密钥的长度(以位为单位)。

27.6 AesDerivedKeyParams 字典

WebIDLdictionary AesDerivedKeyParams : Algorithm {
  required [EnforceRange] unsigned short length;
};

length 成员表示密钥的长度(以位为单位)。

27.7 操作

27.7.1 加密

  1. 如果 normalizedAlgorithmcounter 成员的 长度 不是 16 字节,则 抛出 一个 OperationError

  2. 如果 normalizedAlgorithmlength 成员为零或大于 128,则 抛出 一个 OperationError

  3. ciphertext 为执行 [NIST-SP800-38A] 第 6.5 节中描述的 CTR 加密操作的结果,其中使用 AES 作为分组密码,normalizedAlgorithmcounter 成员作为计数器块的初始值,normalizedAlgorithmlength 成员作为输入参数 m 传递给 [NIST-SP800-38A] 附录 B.1 中定义的标准计数器块增量函数,并以 plaintext 作为输入明文。

  4. 返回 ciphertext

27.7.2 解密

  1. 如果 normalizedAlgorithmcounter 成员的 长度 不是 16 字节,则 抛出 一个 OperationError

  2. 如果 normalizedAlgorithmlength 成员为零或大于 128,则 抛出 一个 OperationError

  3. plaintext 为执行 [NIST-SP800-38A] 第 6.5 节中描述的 CTR 解密操作的结果,其中使用 AES 作为分组密码,normalizedAlgorithmcounter 成员作为计数器块的初始值,normalizedAlgorithmlength 成员作为输入参数 m 传递给 [NIST-SP800-38A] 附录 B.1 中定义的标准计数器块增量函数,并以 ciphertext 作为输入密文。

  4. 返回 plaintext

27.7.3 生成密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 normalizedAlgorithmlength 成员不等于 128、192 或 256 之一,则 抛出 一个 OperationError

  3. 生成长度等于 normalizedAlgorithmlength 成员的 AES 密钥。

  4. 如果密钥生成步骤失败,则 抛出 一个 OperationError

  5. key 为表示所生成的 AES 密钥的新 CryptoKey 对象。

  6. algorithm 为一个新的 AesKeyAlgorithm

  7. algorithmname 属性设置为 "AES-CTR"。

  8. algorithmlength 属性设置为等于 normalizedAlgorithmlength 成员。

  9. key[[type]] 内部槽位设置为 "secret"。

  10. key[[algorithm]] 内部槽位设置为 algorithm

  11. key[[extractable]] 内部槽位设置为 extractable

  12. key[[usages]] 内部槽位设置为 usages

  13. 返回 key

27.7.4 导入密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 format 为 "raw"
    1. datakeyData

    2. 如果 data位长度 不是 128、192 或 256,则 抛出 一个 DataError

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkkty 字段不是 "oct",则 抛出 一个 DataError

    3. 如果 jwk 不符合 JSON Web Algorithms [JWA] 第 6.4 节的要求,则 抛出 一个 DataError

    4. data 为通过解码 jwkk 字段获得的 字节序列

    5. 如果 data位长度 为 128
      如果 jwkalg 字段存在且不是 "A128CTR",则 抛出 一个 DataError
      如果 data位长度 为 192
      如果 jwkalg 字段存在且不是 "A192CTR",则 抛出 一个 DataError
      如果 data位长度 为 256
      如果 jwkalg 字段存在且不是 "A256CTR",则 抛出 一个 DataError
      否则
      抛出 DataError
    6. 如果 usages 非空且 jwkuse 字段存在且不是 "enc",则 抛出 一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效或不包含所有指定的 usages 值,则 抛出 一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 一个 DataError

    否则
    抛出 NotSupportedError
  3. key 为一个表示值为 data 的 AES 密钥的新 CryptoKey 对象。

  4. key[[type]] 内部槽位设置为 "secret"。

  5. algorithm 为一个新的 AesKeyAlgorithm

  6. algorithmname 属性设置为 "AES-CTR"。

  7. algorithmlength 属性设置为 data 的长度(以位为单位)。

  8. key[[algorithm]] 内部槽位设置为 algorithm

  9. 返回 key

27.7.5 导出密钥

  1. 如果无法访问由 key[[handle]] 内部槽位表示的底层加密密钥材料,则 抛出 一个 OperationError

  2. 如果 format 为 "raw"
    1. data 为一个包含由 key[[handle]] 内部槽位所表示的密钥的原始八位字节的 字节序列

    2. resultdata

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 "oct"。

    3. jwkk 属性设置为一个包含由 key[[handle]] 内部槽位表示的密钥的原始八位字节的字符串,并按照 JSON Web Algorithms [JWA] 的第 6.4 节进行编码。

    4. 如果 keylength 属性为 128
      jwkalg 属性设置为字符串 "A128CTR"。
      如果 keylength 属性为 192
      jwkalg 属性设置为字符串 "A192CTR"。
      如果 keylength 属性为 256
      jwkalg 属性设置为字符串 "A256CTR"。
    5. jwkkey_ops 属性设置为等于 key[[usages]] 内部槽位。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽位。

    7. resultjwk

    否则

    抛出 NotSupportedError

  3. 返回 result

27.7.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不是 128、192 或 256,则 抛出 一个 OperationError

  2. 返回 normalizedDerivedKeyAlgorithmlength 成员。

28. AES-CBC

28.1 描述

本节是非规范性的。

"AES-CBC" 算法标识符用于使用 AES 在密码块链接(CBC)模式下执行加密和解密,如 [NIST-SP800-38A] 中所述。

在 CBC 模式下运行时,非 AES 块大小(16 字节)精确倍数的消息可以使用各种填充方案进行填充。在 Web Crypto API 中,支持的唯一填充模式是 PKCS#7,如 [RFC2315] 第 10.3 节第 2 步中所述。

28.2 注册

此算法的 可识别算法名称 是 "AES-CBC"。

操作 参数 结果
encrypt(加密) AesCbcParams byte sequence (字节序列)
decrypt(解密) AesCbcParams byte sequence (字节序列)
generateKey(生成密钥) AesKeyGenParams CryptoKey
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object
get key length(获取密钥长度) AesDerivedKeyParams Integer

28.3 AesCbcParams 字典

WebIDLdictionary AesCbcParams : Algorithm {
  required BufferSource iv;
};

iv 成员表示初始化向量。它 必须为 16 字节。

28.4 操作

28.4.1 加密

  1. 如果 normalizedAlgorithmiv 成员的 长度 不是 16 字节,则 抛出 一个 OperationError

  2. paddedPlaintext 为根据 [RFC2315] 第 10.3 节第 2 步中定义的程序向 plaintext 添加填充八位字节的结果,其中 k 的值为 16。

  3. ciphertext 为执行 [NIST-SP800-38A] 第 6.2 节中描述的 CBC 加密操作的结果,其中使用 AES 作为分组密码,normalizedAlgorithmiv 成员作为 IV 输入参数,paddedPlaintext 作为输入明文。

  4. 返回 ciphertext

28.4.2 解密

  1. 如果 normalizedAlgorithmiv 成员的 长度 不是 16 字节,则 抛出 一个 OperationError

  2. 如果 ciphertext 的长度为零或不是 16 字节的倍数,则 抛出 一个 OperationError

  3. paddedPlaintext 为执行 [NIST-SP800-38A] 第 6.2 节中描述的 CBC 解密操作的结果,其中使用 AES 作为分组密码,normalizedAlgorithmiv 成员作为 IV 输入参数,ciphertext 作为输入密文。

  4. ppaddedPlaintext 的最后一个八位字节的值。

  5. 如果 p 为零或大于 16,或者如果 paddedPlaintext 的最后 p 个八位字节中的任何一个的值不等于 p,则 抛出 一个 OperationError

  6. plaintext 为从 paddedPlaintext 末尾移除 p 个八位字节的结果。

  7. 返回 plaintext

28.4.3 生成密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 normalizedAlgorithmlength 成员不等于 128、192 或 256 之一,则 抛出 一个 OperationError

  3. 生成长度等于 normalizedAlgorithmlength 成员的 AES 密钥。

  4. 如果密钥生成步骤失败,则 抛出 一个 OperationError

  5. key 为表示所生成的 AES 密钥的新 CryptoKey 对象。

  6. algorithm 为一个新的 AesKeyAlgorithm

  7. algorithmname 属性设置为 "AES-CBC"。

  8. algorithmlength 属性设置为等于 normalizedAlgorithmlength 成员。

  9. key[[type]] 内部槽位设置为 "secret"。

  10. key[[algorithm]] 内部槽位设置为 algorithm

  11. key[[extractable]] 内部槽位设置为 extractable

  12. key[[usages]] 内部槽位设置为 usages

  13. 返回 key

28.4.4 导入密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 format 为 "raw"
    1. datakeyData

    2. 如果 data位长度 不是 128、192 或 256,则 抛出 一个 DataError

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkkty 字段不是 "oct",则 抛出 一个 DataError

    3. 如果 jwk 不符合 JSON Web Algorithms [JWA] 第 6.4 节的要求,则 抛出 一个 DataError

    4. data 为通过解码 jwkk 字段获得的 字节序列

    5. 如果 data位长度 为 128
      如果 jwkalg 字段存在且不是 "A128CBC",则 抛出 一个 DataError
      如果 data位长度 为 192
      如果 jwkalg 字段存在且不是 "A192CBC",则 抛出 一个 DataError
      如果 data位长度 为 256
      如果 jwkalg 字段存在且不是 "A256CBC",则 抛出 一个 DataError
      否则
      抛出 DataError
    6. 如果 usages 非空且 jwkuse 字段存在且不是 "enc",则 抛出 一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效或不包含所有指定的 usages 值,则 抛出 一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则 抛出 一个 DataError

    否则
    抛出一个 NotSupportedError
  3. key 为一个表示值为 data 的 AES 密钥的新 CryptoKey 对象。

  4. key[[type]] 内部槽位设置为 "secret"。

  5. algorithm 为一个新的 AesKeyAlgorithm

  6. algorithmname 属性设置为 "AES-CBC"。

  7. algorithmlength 属性设置为 data 的长度(以位为单位)。

  8. key[[algorithm]] 内部槽位设置为 algorithm

  9. 返回 key

28.4.5 导出密钥

  1. 如果无法访问由 key[[handle]] 内部槽位表示的底层加密密钥材料,则 抛出 一个 OperationError

  2. 如果 format 为 "raw"
    1. data 为一个包含由 key[[handle]] 内部槽位所表示的密钥的原始八位字节的 字节序列

    2. resultdata

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 "oct"。

    3. jwkk 属性设置为包含由 key[[handle]] 内部槽表示的密钥原始八位字节的字符串,并根据 JSON Web Algorithms [JWA] 第 6.4 节进行编码。

    4. 如果 keylength 属性为 128
      jwkalg 属性设置为字符串 "A128CBC"。
      如果 keylength 属性为 192
      jwkalg 属性设置为字符串 "A192CBC"。
      如果 keylength 属性为 256
      jwkalg 属性设置为字符串 "A256CBC"。
    5. jwkkey_ops 属性设置为等于 keyusages 属性。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    7. resultjwk

    否则

    抛出 NotSupportedError

  3. 返回 result

28.4.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不为 128、192 或 256,则抛出一个 OperationError

  2. 返回 normalizedDerivedKeyAlgorithmlength 成员。

29. AES-GCM

29.1 描述

本节是非规范性的。

"AES-GCM" 算法标识符用于使用 Galois/Counter Mode (GCM) 模式下的 AES 执行认证加密和解密,如 [NIST-SP800-38D] 所述。

29.2 注册

该算法的公认算法名称为 "AES-GCM"。

操作 参数 结果
encrypt(加密) AesGcmParams byte sequence (字节序列)
decrypt(解密) AesGcmParams byte sequence (字节序列)
generateKey(生成密钥) AesKeyGenParams CryptoKey
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object
get key length(获取密钥长度) AesDerivedKeyParams Integer

29.3 AesGcmParams 字典

WebIDLdictionary AesGcmParams : Algorithm {
  required BufferSource iv;
  BufferSource additionalData;
  [EnforceRange] octet tagLength;
};

iv 成员表示要使用的初始化向量。长度最大可达 2^64-1 字节。

additionalData 成员表示要包含的附加认证数据。

tagLength 成员表示所需的认证标签长度。可以为 0 到 128。

29.4 操作

29.4.1 加密

  1. 如果 plaintext长度大于 2^39 - 256 字节,则抛出一个 OperationError

  2. 如果 normalizedAlgorithmiv 成员的长度大于 2^64 - 1 字节,则抛出一个 OperationError

  3. 如果 normalizedAlgorithmadditionalData 成员存在且长度大于 2^64 - 1 字节,则抛出一个 OperationError

  4. 如果 normalizedAlgorithmtagLength 成员不存在
    tagLength 为 128。
    如果 normalizedAlgorithmtagLength 成员为 32、64、96、104、112、120 或 128 中的一个
    tagLength 等于 normalizedAlgorithmtagLength 成员
    否则
    抛出 一个 OperationError
  5. additionalDatanormalizedAlgorithmadditionalData 成员(如果存在),否则为一个空的字节序列

  6. CT 为使用 AES 作为块密码,以 normalizedAlgorithmiv 成员作为 IV 输入参数,additionalData 作为 A 输入参数,tagLength 作为 t 先决条件,以及 plaintext 作为输入明文,执行 [NIST-SP800-38D] 第 7.1 节所述的认证加密函数所产生的结果。

  7. ciphertext 等于 C | T,其中 '|' 表示拼接。

  8. 返回 ciphertext

29.4.2 解密

  1. 如果 normalizedAlgorithmtagLength 成员不存在
    tagLength 为 128。
    如果 normalizedAlgorithmtagLength 成员为 32、64、96、104、112、120 或 128 中的一个
    tagLength 等于 normalizedAlgorithmtagLength 成员
    否则
    抛出 一个 OperationError
  2. 如果 ciphertext位长度小于 tagLength,则抛出一个 OperationError

  3. 如果 normalizedAlgorithmiv 成员的长度大于 2^64 - 1 字节,则抛出一个 OperationError

  4. 如果 normalizedAlgorithmadditionalData 成员存在且长度大于 2^64 - 1 字节,则抛出一个 OperationError

  5. tagciphertext 的最后 tagLength 位。

  6. actualCiphertext 为从 ciphertext 中移除最后 tagLength 位后的结果。

  7. additionalDatanormalizedAlgorithmadditionalData 成员(如果存在),否则为一个空的字节序列

  8. 执行 [NIST-SP800-38D] 第 7.2 节所述的认证解密函数,使用 AES 作为块密码,normalizedAlgorithmiv 成员作为 IV 输入参数,additionalData 作为 A 输入参数,tagLength 作为 t 先决条件,actualCiphertext 作为输入密文,Ctag 作为认证标签 T

    如果算法结果为认证失败,即 "FAIL"
    抛出一个 OperationError
    否则
    plaintext 为认证解密函数的输出 P
  9. 返回 plaintext

29.4.3 生成密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 normalizedAlgorithmlength 成员不等于 128、192 或 256 中的一个,则抛出一个 OperationError

  3. 生成长度等于 normalizedAlgorithmlength 成员的 AES 密钥。

  4. 如果密钥生成步骤失败,则 抛出 一个 OperationError

  5. key 为表示生成的 AES 密钥的新 CryptoKey 对象。

  6. algorithm 为一个新的 AesKeyAlgorithm

  7. algorithmname 属性设置为 "AES-GCM"。

  8. algorithmlength 属性设置为等于 normalizedAlgorithmlength 成员。

  9. key[[type]] 内部槽设置为 "secret"。

  10. key[[algorithm]] 内部槽设置为 algorithm

  11. key[[extractable]] 内部槽设置为 extractable

  12. key[[usages]] 内部槽设置为 usages

  13. 返回 key

29.4.4 导入密钥

  1. 如果 usages 包含任何不是 "encrypt"、"decrypt"、"wrapKey" 或 "unwrapKey" 之一的条目,则 抛出 一个 SyntaxError

  2. 如果 format 为 "raw"
    1. datakeyData

    2. 如果 data位长度不是 128、192 或 256,则抛出一个 DataError

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkkty 字段不为 "oct",则抛出一个 DataError

    3. 如果 jwk 不符合 JSON Web Algorithms [JWA] 第 6.4 节的要求,则 抛出 一个 DataError

    4. data 为通过解码 jwkk 字段获得的字节序列

    5. 如果 data位长度为 128
      如果 jwkalg 字段存在,且不为 "A128GCM",则抛出一个 DataError
      如果 data位长度为 192
      如果 jwkalg 字段存在,且不为 "A192GCM",则抛出一个 DataError
      如果 data位长度为 256
      如果 jwkalg 字段存在,且不为 "A256GCM",则抛出一个 DataError
      否则
      抛出 DataError
    6. 如果 usages 非空,且 jwkuse 字段存在且不为 "enc",则抛出一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则抛出一个 DataError

    否则
    抛出 NotSupportedError
  3. key 为表示值 data 的 AES 密钥的新 CryptoKey 对象。

  4. key[[type]] 内部槽设置为 "secret"。

  5. algorithm 为一个新的 AesKeyAlgorithm

  6. algorithmname 属性设置为 "AES-GCM"。

  7. algorithmlength 属性设置为 data 的位长度。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

29.4.5 导出密钥

  1. 如果无法访问由 key[[handle]] 内部槽表示的底层加密密钥材料,则抛出一个 OperationError

  2. 如果 format 为 "raw"
    1. data 为包含由 key[[handle]] 内部槽表示的密钥原始八位字节的字节序列

    2. resultdata

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 "oct"。

    3. jwkk 属性设置为包含由 key[[handle]] 内部槽表示的密钥原始八位字节的字符串,并根据 JSON Web Algorithms [JWA] 第 6.4 节进行编码。

    4. 如果 keylength 属性为 128
      jwkalg 属性设置为字符串 "A128GCM"。
      如果 keylength 属性为 192
      jwkalg 属性设置为字符串 "A192GCM"。
      如果 keylength 属性为 256
      jwkalg 属性设置为字符串 "A256GCM"。
    5. jwkkey_ops 属性设置为等于 keyusages 属性。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    7. resultjwk

    否则

    抛出 NotSupportedError

  3. 返回 result

29.4.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不为 128、192 或 256,则抛出一个 OperationError

  2. 返回 normalizedDerivedKeyAlgorithmlength 成员。

30. AES-KW

30.1 描述

本节是非规范性的。

"AES-KW" 算法标识符用于执行 AES 密钥封装,如 [RFC3394] 所述。

30.2 注册

该算法的公认算法名称为 "AES-KW"。

操作 参数 结果
wrapKey(封装密钥) byte sequence (字节序列)
unwrapKey(解封装密钥) byte sequence (字节序列)
generateKey(生成密钥) AesKeyGenParams CryptoKey
importKey(导入密钥) CryptoKey
exportKey(导出密钥) object
get key length(获取密钥长度) AesDerivedKeyParams Integer

30.3 操作

30.3.1 封装密钥 (Wrap Key)

  1. 如果 plaintext 的长度不是 64 位的倍数,则抛出一个 OperationError

  2. ciphertext 为使用 plaintext 作为要封装的明文,并使用同文档第 2.2.3.1 节定义的默认初始值,执行 [RFC3394] 第 2.2.1 节所述的密钥封装操作的结果。

  3. 返回 ciphertext

30.3.2 解封装密钥 (Unwrap Key)

  1. plaintext 为使用 ciphertext 作为输入密文,并使用同文档第 2.2.3.1 节定义的默认初始值,执行 [RFC3394] 第 2.2.2 节所述的密钥解封装操作的结果。

  2. 如果密钥解封装操作返回错误,则抛出一个 OperationError

  3. 返回 plaintext

30.3.3 生成密钥

  1. 如果 usages 包含任何不是 "wrapKey" 或 "unwrapKey" 的条目,则抛出一个 SyntaxError

  2. 如果 normalizedAlgorithmlength 属性不等于 128、192 或 256 中的一个,则抛出一个 OperationError

  3. 生成长度等于 normalizedAlgorithmlength 成员的 AES 密钥。

  4. 如果密钥生成步骤失败,则 抛出 一个 OperationError

  5. key 为表示生成的 AES 密钥的新 CryptoKey 对象。

  6. algorithm 为一个新的 AesKeyAlgorithm

  7. algorithmname 属性设置为 "AES-KW"。

  8. algorithmlength 属性设置为等于 normalizedAlgorithmlength 属性。

  9. key[[type]] 内部槽设置为 "secret"。

  10. key[[algorithm]] 内部槽设置为 algorithm

  11. key[[extractable]] 内部槽设置为 extractable

  12. key[[usages]] 内部槽设置为 usages

  13. 返回 key

30.3.4 导入密钥

  1. 如果 usages 包含一个不是 "wrapKey" 或 "unwrapKey" 的条目,则抛出一个 SyntaxError

  2. 如果 format 为 "raw"
    1. datakeyData

    2. 如果 data位长度不是 128、192 或 256,则抛出一个 DataError

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkkty 字段不为 "oct",则抛出一个 DataError

    3. 如果 jwk 不符合 JSON Web Algorithms [JWA] 第 6.4 节的要求,则 抛出 一个 DataError

    4. data 为通过解码 jwkk 字段获得的字节序列

    5. 如果 data位长度为 128
      如果 jwkalg 字段存在,且不为 "A128KW",则抛出一个 DataError
      如果 data位长度为 192
      如果 jwkalg 字段存在,且不为 "A192KW",则抛出一个 DataError
      如果 data位长度为 256
      如果 jwkalg 字段存在,且不为 "A256KW",则抛出一个 DataError
      否则
      抛出 DataError
    6. 如果 usages 非空,且 jwkuse 字段存在且不为 "enc",则抛出一个 DataError

    7. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    8. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则抛出一个 DataError

    否则
    抛出 NotSupportedError
  3. key 为一个表示值为 data 的 AES 密钥的新 CryptoKey

  4. key[[type]] 内部槽设置为 "secret"。

  5. algorithm 为一个新的 AesKeyAlgorithm

  6. algorithmname 属性设置为 "AES-KW"。

  7. algorithmlength 属性设置为 data 的位长度。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

30.3.5 导出密钥

  1. 如果无法访问由 key[[handle]] 内部槽表示的底层加密密钥材料,则抛出一个 OperationError

  2. 如果 format 为 "raw"
    1. data 为包含由 key[[handle]] 内部槽表示的密钥原始八位字节的字节序列

    2. resultdata

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 "oct"。

    3. jwkk 属性设置为包含由 key[[handle]] 内部槽表示的密钥原始八位字节的字符串,并根据 JSON Web Algorithms [JWA] 第 6.4 节进行编码。

    4. 如果 keylength 属性为 128
      jwkalg 属性设置为字符串 "A128KW"。
      如果 keylength 属性为 192
      jwkalg 属性设置为字符串 "A192KW"。
      如果 keylength 属性为 256
      jwkalg 属性设置为字符串 "A256KW"。
    5. jwkkey_ops 属性设置为等于 keyusages 属性。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    7. resultjwk

    否则

    抛出 NotSupportedError

  3. 返回 result

30.3.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不为 128、192 或 256,则抛出一个 OperationError

  2. 返回 normalizedDerivedKeyAlgorithmlength 成员。

31. HMAC

31.1 描述

本节是非规范性的。

HMAC 算法根据 [FIPS-198-1] 并使用本规范中定义的 SHA 哈希函数来计算和验证基于哈希的消息认证码。

其他规范可以指定将额外的哈希算法与 HMAC 一起使用。此类规范必须定义额外哈希算法的摘要操作,以及 HMAC 的密钥导入步骤密钥导出步骤

31.2 注册

该算法的公认算法名称为 "HMAC"。

操作 参数 结果
符号 byte sequence (字节序列)
verify(验证) boolean
generateKey(生成密钥) HmacKeyGenParams CryptoKey
importKey(导入密钥) HmacImportParams CryptoKey
exportKey(导出密钥) object
get key length(获取密钥长度) HmacImportParams Integer

31.3 HmacImportParams 字典

WebIDLdictionary HmacImportParams : Algorithm {
  required HashAlgorithmIdentifier hash;
  [EnforceRange] unsigned long length;
};

hash 成员表示要使用的内部哈希函数。

length 成员表示密钥的长度(以位为单位)。

31.4 HmacKeyAlgorithm 字典

WebIDLdictionary HmacKeyAlgorithm : KeyAlgorithm {
  required KeyAlgorithm hash;
  required unsigned long length;
};

hash 成员表示要使用的内部哈希函数。

length 成员表示密钥的长度(以位为单位)。

31.5 HmacKeyGenParams 字典

WebIDLdictionary HmacKeyGenParams : Algorithm {
  required HashAlgorithmIdentifier hash;
  [EnforceRange] unsigned long length;
};

hash 成员表示要使用的内部哈希函数。

length 成员表示要生成的密钥的长度(以位为单位)。如果未指定,将使用建议的长度,即相关哈希函数的块大小。

31.6 操作

31.6.1 签名

  1. mac 为使用 key[[handle]] 内部槽表示的密钥、由 key[[algorithm]] 内部槽的 hash 属性标识的哈希函数,以及 message 作为输入数据 text,执行 [FIPS-198-1] 第 4 节所述的 MAC 生成操作的结果。

  2. 返回 mac

31.6.2 验证

  1. mac 为使用 key[[handle]] 内部槽表示的密钥、由 key[[algorithm]] 内部槽的 hash 属性标识的哈希函数,以及 message 作为输入数据 text,执行 [FIPS-198-1] 第 4 节所述的 MAC 生成操作的结果。

  2. 如果 mac 等于 signature,则返回 true,否则返回 false。

31.6.3 生成密钥

  1. 如果 usages 包含任何不是 "sign" 或 "verify" 的条目,则抛出一个 SyntaxError

  2. 如果 normalizedAlgorithmlength 成员不存在
    length 为由 normalizedAlgorithmhash 成员标识的哈希函数的块大小(以位为单位)。
    否则,如果 normalizedAlgorithmlength 成员非零
    length 等于 normalizedAlgorithmlength 成员。
    否则
    抛出 一个 OperationError
  3. 生成一个长度为 length 位的密钥。

  4. 如果密钥生成步骤失败,则 抛出 一个 OperationError

  5. key 为表示生成的密钥的新 CryptoKey 对象。

  6. algorithm 为一个新的 HmacKeyAlgorithm

  7. algorithmname 属性设置为 "HMAC"。

  8. algorithmlength 属性设置为 length

  9. hash 为一个新的 KeyAlgorithm

  10. hashname 属性设置为等于 normalizedAlgorithmhash 成员的 name 成员。

  11. algorithmhash 属性设置为 hash

  12. key[[type]] 内部槽设置为 "secret"。

  13. key[[algorithm]] 内部槽设置为 algorithm

  14. key[[extractable]] 内部槽设置为 extractable

  15. key[[usages]] 内部槽设置为 usages

  16. 返回 key

31.6.4 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 usages 包含一个非 “sign” 或 “verify” 的条目,则 抛出 SyntaxError

  3. hash 为一个新的 KeyAlgorithm

  4. 如果 format 为 "raw"
    1. datakeyData

    2. hash 设置为等于 normalizedAlgorithmhash 成员。

    如果 format 为 "jwk"
    1. 如果 keyData 是一个 JsonWebKey 字典

      jwk 等于 keyData

      否则

      抛出 DataError

    2. 如果 jwkkty 字段不为 "oct",则抛出一个 DataError

    3. 如果 jwk 不符合 JSON Web Algorithms [JWA] 第 6.4 节的要求,则 抛出 一个 DataError

    4. data 为通过解码 jwkk 字段获得的字节序列

    5. hash 设置为等于 normalizedAlgorithmhash 成员。

    6. 如果 hashname 属性为 "SHA-1"
      如果 jwkalg 字段存在且不为 "HS1",则抛出一个 DataError
      如果 hashname 属性为 "SHA-256"
      如果 jwkalg 字段存在且不为 "HS256",则抛出一个 DataError
      如果 hashname 属性为 "SHA-384"
      如果 jwkalg 字段存在且不为 "HS384",则抛出一个 DataError
      如果 hashname 属性为 "SHA-512"
      如果 jwkalg 字段存在且不为 "HS512",则抛出一个 DataError
      否则,如果 hashname 属性在另一个适用规范中定义
      执行由其他适用规范定义的任何密钥导入步骤,传入 formatjwkhash 并获得 hash
    7. 如果 usages 非空,且 jwkuse 字段存在且不为 "sign",则抛出一个 DataError

    8. 如果 jwkkey_ops 字段存在,且根据 JSON Web Key [JWK] 的要求无效,或者未包含所有指定的 usages 值,则抛出一个 DataError

    9. 如果 jwkext 字段存在且值为 false,而 extractable 为 true,则抛出一个 DataError

    否则
    抛出 NotSupportedError
  5. lengthdata位长度

  6. 如果 length 为零,则抛出一个 DataError

  7. 如果 normalizedAlgorithmlength 成员存在
    如果 normalizedAlgorithmlength 成员大于 length
    抛出 DataError
    如果 normalizedAlgorithmlength 成员小于或等于 length 减去 8
    抛出 DataError
    否则
    length 设置为等于 normalizedAlgorithmlength 成员。
  8. key 为一个新的 CryptoKey 对象,表示一个具有 data 的前 length 位的 HMAC 密钥。

  9. key[[type]] 内部槽设置为 "secret"。

  10. algorithm 为一个新的 HmacKeyAlgorithm

  11. algorithmname 属性设置为 "HMAC"。

  12. algorithmlength 属性设置为 length

  13. algorithmhash 属性设置为 hash

  14. key[[algorithm]] 内部槽设置为 algorithm

  15. 返回 key

31.6.5 导出密钥

  1. 如果无法访问由 key[[handle]] 内部槽表示的底层加密密钥材料,则抛出一个 OperationError

  2. bits 为由 key[[handle]] 内部槽表示的密钥的原始位。

  3. data 为一个包含 bits字节序列

  4. 如果 format 为 "raw"
    1. resultdata

    如果 format 为 "jwk"
    1. jwk 为一个新的 JsonWebKey 字典。

    2. jwkkty 属性设置为字符串 "oct"。

    3. jwkk 属性设置为包含 data 的字符串,并根据 JSON Web Algorithms [JWA] 第 6.4 节进行编码。

    4. algorithmkey[[algorithm]] 内部槽。

    5. hashalgorithmhash 属性。

    6. 如果 hashname 属性为 "SHA-1"
      jwkalg 属性设置为字符串 "HS1"。
      如果 hashname 属性为 "SHA-256"
      jwkalg 属性设置为字符串 "HS256"。
      如果 hashname 属性为 "SHA-384"
      jwkalg 属性设置为字符串 "HS384"。
      如果 hashname 属性为 "SHA-512"
      jwkalg 属性设置为字符串 "HS512"。
      否则,hashname 属性在另一个适用规范中定义
      1. 执行由其他适用规范定义的任何密钥导出步骤,传入 formatkey 并获得 alg

      2. jwkalg 属性设置为 alg

    7. jwkkey_ops 属性设置为等于 keyusages 属性。

    8. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    9. resultjwk

    否则

    抛出 NotSupportedError

  5. 返回 result

31.6.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不存在

    length 为由 normalizedDerivedKeyAlgorithmhash 成员标识的哈希函数的块大小(以位为单位)。

    否则,如果 normalizedDerivedKeyAlgorithmlength 成员非零
    length 等于 normalizedDerivedKeyAlgorithmlength 成员。
    否则
    抛出一个 TypeError
  2. 返回 length

32. SHA

32.1 描述

本节是非规范性的。

这描述了由 [FIPS-180-4] 指定的 SHA-1 和 SHA-2 系列。

32.2 注册

对应的公认算法名称为 "SHA-1"、"SHA-256"、"SHA-384" 和 "SHA-512"。

操作 参数 结果
digest(摘要) byte sequence (字节序列)

32.3 操作

32.3.1 摘要 (Digest)

  1. 如果 normalizedAlgorithmname 成员是区分大小写的字符串匹配 "SHA-1"
    result 为使用 message 作为输入消息 M,执行 [FIPS-180-4] 第 6.1 节中定义的 SHA-1 哈希函数的结果。
    如果 normalizedAlgorithmname 成员是区分大小写的字符串匹配 "SHA-256"
    result 为使用 message 作为输入消息 M,执行 [FIPS-180-4] 第 6.2 节中定义的 SHA-256 哈希函数的结果。
    如果 normalizedAlgorithmname 成员是区分大小写的字符串匹配 "SHA-384"
    result 为使用 message 作为输入消息 M,执行 [FIPS-180-4] 第 6.5 节中定义的 SHA-384 哈希函数的结果。
    如果 normalizedAlgorithmname 成员是区分大小写的字符串匹配 "SHA-512"
    result 为使用 message 作为输入消息 M,执行 [FIPS-180-4] 第 6.4 节中定义的 SHA-512 哈希函数的结果。
  2. 如果执行该操作导致错误,则 抛出 OperationError

  3. 返回 result

33. HKDF

33.1 描述

本节是非规范性的。

"HKDF" 算法标识符用于使用 [RFC5869] 中描述的提取然后扩展方法,并使用本规范中定义的 SHA 哈希函数执行密钥派生。

其他规范可以指定将额外的哈希算法与 HKDF 一起使用。此类规范必须定义额外哈希算法的摘要操作。

33.2 注册

该算法的公认算法名称为 "HKDF"。

操作 参数 结果
deriveBits(派生比特) HkdfParams byte sequence (字节序列)
importKey(导入密钥) CryptoKey
获取密钥长度 null

33.3 HkdfParams 字典

WebIDLdictionary HkdfParams : Algorithm {
  required HashAlgorithmIdentifier hash;
  required BufferSource salt;
  required BufferSource info;
};

hash 成员表示要与 HMAC 一起使用的算法(例如:SHA-256)。

salt 成员表示在提取步骤中使用的盐。

info 成员表示派生密钥材料的应用程序特定上下文。

33.4 操作

33.4.1 派生位

  1. 如果 length 为 null 或不是 8 的倍数,则抛出一个 OperationError

  2. keyDerivationKey 为由 key[[handle]] 内部槽表示的密钥。

  3. result 为执行 [RFC5869] 第 2 节中所述的 HKDF 提取然后 HKDF 扩展步骤的结果,使用

    • normalizedAlgorithmhash 成员作为 Hash

    • keyDerivationKey 作为输入密钥材料 IKM

    • normalizedAlgorithmsalt 成员作为 salt

    • normalizedAlgorithminfo 成员作为 info

    • length 除以 8 作为 L 的值,

  4. 如果密钥派生操作失败,则抛出一个 OperationError

  5. 返回 result

33.4.2 导入密钥

  1. keyData 为要导入的密钥数据。

  2. 如果 format 为 "raw"
    1. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的值,则抛出一个 SyntaxError

    2. 如果 extractable 不为 false,则抛出一个 SyntaxError

    3. key 为一个表示 keyData 中提供的密钥数据的新 CryptoKey 对象。

    4. key[[type]] 内部槽设置为 "secret"。

    5. algorithm 为一个新的 KeyAlgorithm 对象。

    6. algorithmname 属性设置为 "HKDF"。

    7. key[[algorithm]] 内部槽设置为 algorithm

    8. 返回 key

    否则
    抛出 NotSupportedError

33.4.3 获取密钥长度

  1. 返回 null。

34. PBKDF2

34.1 描述

本节是非规范性的。

"PBKDF2" 算法标识符用于根据 [RFC8018],使用 HMAC 作为伪随机函数,并使用本规范中定义的 SHA 哈希函数执行基于密码的密钥派生函数 2 (PKCS#5) 的密钥派生。

其他规范可以指定将额外的哈希算法与 PBKDF2 一起使用。此类规范必须定义额外哈希算法的摘要操作。

34.2 注册

该算法的公认算法名称为 "PBKDF2"。

操作 参数 结果
deriveBits(派生比特) Pbkdf2Params byte sequence (字节序列)
importKey(导入密钥) CryptoKey
获取密钥长度 null

34.3 Pbkdf2Params 字典

WebIDLdictionary Pbkdf2Params : Algorithm {
  required BufferSource salt;
  required [EnforceRange] unsigned long iterations;
  required HashAlgorithmIdentifier hash;
};

Pbkdf2Params 字典包含一个 salt 成员、一个 iterations 成员和一个 hash 成员。

34.4 操作

34.4.1 派生位

  1. 如果 length 为 null 或不是 8 的倍数,则抛出一个 OperationError

  2. 如果 normalizedAlgorithmiterations 成员为零,则抛出一个 OperationError

  3. 如果 length 为零,则返回一个空的字节序列

  4. prf 为使用由 normalizedAlgorithmhash 成员描述的哈希函数,执行 [FIPS-198-1] 第 4 节中所述的 MAC 生成函数。

  5. result 为使用 prf 作为伪随机函数 PRF,以 key[[handle]] 内部槽表示的密码作为密码 P,以 normalizedAlgorithmsalt 属性作为盐 S,以 normalizedAlgorithmiterations 属性的值作为迭代次数 c,以及 length 除以 8 作为预期密钥长度 dkLen,执行 [RFC8018] 第 5.2 节中定义的 PBKDF2 操作的结果。

  6. 如果密钥派生操作失败,则抛出一个 OperationError

  7. 返回 result

34.4.2 导入密钥

  1. 如果 format 不为 "raw",则抛出一个 NotSupportedError

  2. 如果 usages 包含一个不是 "deriveKey" 或 "deriveBits" 的值,则抛出一个 SyntaxError

  3. 如果 extractable 不为 false,则抛出一个 SyntaxError

  4. key 为一个新的 CryptoKey,表示 keyData

  5. key[[type]] 内部槽设置为 "secret"。

  6. algorithm 为一个新的 KeyAlgorithm 对象。

  7. algorithmname 属性设置为 "PBKDF2"。

  8. key[[algorithm]] 内部槽设置为 algorithm

  9. 返回 key

34.4.3 获取密钥长度

  1. 返回 null。

35. JavaScript 示例代码

35.1 生成两个密钥对,派生一个共享密钥,加密一些数据

此示例生成两个 X25519 密钥对(一个给 Alice,一个给 Bob),在它们之间执行密钥协商,使用带有 SHA-256 的 HKDF 从结果中派生一个 256 位 AES-GCM 密钥,并用它加密和解密一些数据。

示例 1: X25519 密钥协商
// Generate a key pair for Alice.
const alice_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
const alice_private_key = alice_x25519_key.privateKey;

// Normally, the public key would be sent by Bob to Alice in advance over some authenticated channel.
// In this example, we'll generate another key pair and use its public key instead.
const bob_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
const bob_public_key = bob_x25519_key.publicKey;

// Perform the key agreement.
const alice_x25519_params = { name: 'X25519', public: bob_public_key };
const alice_shared_key = await crypto.subtle.deriveKey(alice_x25519_params, alice_private_key, 'HKDF', false /* extractable */, ['deriveKey']);

// Derive a symmetric key from the result.
const salt = crypto.getRandomValues(new Uint8Array(32));
const info = new TextEncoder().encode('X25519 key agreement for an AES-GCM-256 key');
const hkdf_params = { name: 'HKDF', hash: 'SHA-256', salt, info };
const gcm_params = { name: 'AES-GCM', length: 256 };
const alice_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, alice_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']);

// Encrypt some data with the symmetric key, and send it to Bob. The IV must be passed along as well.
const iv = crypto.getRandomValues(new Uint8Array(12));
const message = new TextEncoder().encode('Hi Bob!');
const encrypted = await crypto.subtle.encrypt({ ...gcm_params, iv }, alice_symmetric_key, message);

// On Bob's side, Alice's public key and Bob's private key are used, instead.
// To get the same result, Alice and Bob must agree on using the same salt and info.
const alice_public_key = alice_x25519_key.publicKey;
const bob_private_key = bob_x25519_key.privateKey;
const bob_x25519_params = { name: 'X25519', public: alice_public_key };
const bob_shared_key = await crypto.subtle.deriveKey(bob_x25519_params, bob_private_key, 'HKDF', false /* extractable */, ['deriveKey']);
const bob_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, bob_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']);

// On Bob's side, the data can be decrypted.
const decrypted = await crypto.subtle.decrypt({ ...gcm_params, iv }, bob_symmetric_key, encrypted);
const decrypted_message = new TextDecoder().decode(decrypted);

35.2 生成一个签名密钥对,对数据进行签名

示例 2: Ed25519 签名
const data = new TextEncoder().encode('Hello, world!');
const key = await crypto.subtle.generateKey('Ed25519', false, ['sign']);
const signature = await crypto.subtle.sign('Ed25519', key.privateKey, data);

35.3 生成一个对称密钥,加密一些数据

示例 3: AES-GCM 加密
const data = new TextEncoder().encode('Hello, world!');
const aesAlgorithmKeyGen = {
  name: 'AES-GCM',
  // AesKeyGenParams
  length: 256
};
const aesAlgorithmEncrypt = {
  name: 'AES-GCM',
  // AesGcmParams
  iv: crypto.getRandomValues(new Uint8Array(16))
};
const key = await crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ['encrypt']);
const encrypted = await crypto.subtle.encrypt(aesAlgorithmEncrypt, key, data);

35.4 为下载生成唯一名称

示例 4: 随机 UUID 生成
const filename = `${crypto.randomUUID()}.txt`;

36. IANA 考量

36.1 JSON Web 签名和加密算法注册

本节在 IANA JSON Web Signature and Encryption Algorithms 注册表中注册了以下算法标识符,供 JSON Web Key 使用。请注意,模板中的“实现要求”字段特别指代与 JSON Web Signature 和 JSON Web Encryption 的结合使用,在这种情况下,禁止使用未认证的加密。

36.2 JSON Web 密钥参数注册

37. 致谢

特别感谢 Ryan Sleevi(原始作者和编辑)以及 Mark Watson(本文档的前任编辑)。

感谢 Adam Barth、Alex Russell、Ali Asad、Arun Ranganathan、Brian Smith、Brian Warner、Channy Yun、Charles Engelke、Eric Roman、Glenn Adams、Jim Schaad、Kai Engert、Michael Hutchinson、Michael B. Jones、Nick Van den Bleeken、Richard Barnes、Ryan Hurst、Tim Taubert、Vijay Bharadwaj、Virginie Galindo 和 Wan-Teh Chang 提供的技术反馈和协助。

感谢 W3C Web Cryptography 工作组,以及 public-webcrypto@w3.org 邮件列表的参与者。

W3C 谨感谢 Northrop Grumman Cybersecurity Research ConsortiumW3C/MIT 的支持。

getRandomValues 接口中的 Crypto 方法最初由 Adam Barth 向 WHATWG 提出。

A. JSON Web 密钥 / JSON Web 算法之间的映射

本节是非规范性的。

有关导入和导出 JWK 的规范性要求,请参阅算法特定的章节。

A.1 算法映射

JSON Web Key AlgorithmIdentifier
{ kty: "RSA",
  alg: "RS1" }
{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-1" }
}
{ kty: "RSA",
  alg: "RS256" }
{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-256" }
}
{ kty: "RSA",
  alg: "RS384" }
{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-384" }
}
{ kty: "RSA",
  alg: "RS512" }
{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-512" }
}
{ kty: "RSA",
  alg: "PS256" }
{ name: "RSA-PSS",
  hash: { name: "SHA-256" }
}
{ kty: "RSA",
  alg: "PS384" }
{ name: "RSA-PSS",
  hash: { name: "SHA-384" }
}
{ kty: "RSA",
  alg: "PS512" }
{ name: "RSA-PSS",
  hash: { name: "SHA-512" }
}
{ kty: "RSA",
  alg: "RSA-OAEP" }
{ name: "RSA-OAEP",
  hash: { name: "SHA-1" }
}
{ kty: "RSA",
  alg: "RSA-OAEP-256" }
{ name: "RSA-OAEP",
  hash: { name: "SHA-256" }
}
{ kty: "RSA",
  alg: "RSA-OAEP-384" }
{ name: "RSA-OAEP",
  hash: { name: "SHA-384" }
}
{ kty: "RSA",
  alg: "RSA-OAEP-512" }
{ name: "RSA-OAEP",
  hash: { name: "SHA-512" }
}
{ kty: "EC",
  alg: "ES256" }
{ name: "ECDSA",
  namedCurve: "P-256",
  hash: { name: "SHA-256" }
}
{ kty: "EC",
  alg: "ES384" }
{ name: "ECDSA",
  namedCurve: "P-384",
  hash: { name: "SHA-384" }
}
{ kty: "EC",
  alg: "ES512" }
{ name: "ECDSA",
  namedCurve: "P-521",
  hash: { name: "SHA-512" }
}
{ kty: "OKP",
  crv: "Ed25519",
  alg: "Ed25519" }
{ name: "Ed25519" }
{ kty: "OKP",
  crv: "X25519" }
{ name: "X25519" }
{ kty: "oct",
  alg: "A128CTR" }
{ name: "AES-CTR",
  length: 128 }
{ kty: "oct",
  alg: "A192CTR" }
{ name: "AES-CTR",
  length: 192 }
{ kty: "oct",
  alg: "A256CTR" }
{ name: "AES-CTR",
  length: 256 }
{ kty: "oct",
  alg: "A128CBC" }
{ name: "AES-CBC",
  length: 128 }
{ kty: "oct",
  alg: "A192CBC" }
{ name: "AES-CBC",
  length: 192 }
{ kty: "oct",
  alg: "A256CBC" }
{ name: "AES-CBC",
  length: 256 }
{ kty: "oct",
  alg: "A128KW" }
{ name: "AES-KW",
  length: 128 }
{ kty: "oct",
  alg: "A192KW" }
{ name: "AES-KW",
  length: 192 }
{ kty: "oct",
  alg: "A256KW" }
{ name: "AES-KW",
  length: 256 }
{ kty: "oct",
  alg: "A128GCM" }
{ name: "AES-GCM",
  length: 128 }
{ kty: "oct",
  alg: "A192GCM" }
{ name: "AES-GCM",
  length: 192 }
{ kty: "oct",
  alg: "A256GCM" }
{ name: "AES-GCM",
  length: 256 }
{ kty: "oct",
  alg: "A128GCMKW" }
{ name: "AES-GCM",
  length: 128 }
{ kty: "oct",
  alg: "A192GCMKW" }
{ name: "AES-GCM",
  length: 192 }
{ kty: "oct",
  alg: "A256GCMKW" }
{ name: "AES-GCM",
  length: 256 }
{ kty: "oct",
  alg: "HS1" }
{ name: "HMAC",
  hash: { name: "SHA-1" }
}
{ kty: "oct",
  alg: "HS256" }
{ name: "HMAC",
  hash: { name: "SHA-256" }
}
{ kty: "oct",
  alg: "HS384" }
{ name: "HMAC",
  hash: { name: "SHA-384" }
}
{ kty: "oct",
  alg: "HS512" }
{ name: "HMAC",
  hash: "SHA-512" }

B. 算法与 SubjectPublicKeyInfo 之间的映射

本节是非规范性的。

有关导入和导出 SPKI 的规范性要求,请参阅算法特定的章节。

算法 OID subjectPublicKey ASN.1 结构 AlgorithmIdentifier 参考
rsaEncryption (1.2.840.113549.1.1.1) RSAPublicKey "RSASSA-PKCS1-v1_5"、"RSA-PSS" 或 "RSA-OAEP" [RFC3447]
id-ecPublicKey (1.2.840.10045.2.1) ECPoint "ECDH" 或 "ECDSA" [RFC5480]
id-Ed25519 (1.3.101.112) BIT STRING "Ed25519" [RFC8410]
id-X25519 (1.3.101.110) BIT STRING "X25519" [RFC8410]

本规范使用的对象标识符不包含有关密钥预期用于的特定算法和哈希的信息。如果需要此信息,建议改为使用 "jwk" 密钥格式。

C. 算法与 PKCS#8 PrivateKeyInfo 之间的映射

本节是非规范性的。

有关导入和导出 PKCS#8 PrivateKeyInfo 的规范性要求,请参阅算法特定的章节。

privateKeyAlgorithm privateKey 格式 AlgorithmIdentifier 参考
rsaEncryption (1.2.840.113549.1.1.1) RSAPrivateKey "RSASSA-PKCS1-v1_5"、"RSA-PSS" 或 "RSA-OAEP" [RFC3447]
id-ecPublicKey (1.2.840.10045.2.1) ECPrivateKey "ECDH" 或 "ECDSA" [RFC5480]
id-Ed25519 (1.3.101.112) CurvePrivateKey "Ed25519" [RFC8410]
id-X25519 (1.3.101.110) CurvePrivateKey "X25519" [RFC8410]

D. 参考文献

D.1 规范性参考文献

[DOM]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript 语言规范. Ecma International. URL: https://tc39.es/ecma262/multipage/
[编码]
编码标准. Anne van Kesteren. WHATWG. 活标准. URL: https://encoding.spec.whatwg.org/
[FIPS-180-4]
FIPS PUB 180-4:安全散列标准 (SHS). 美国商务部/国家标准与技术研究院. 2015年8月. 国家标准. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
[FIPS-198-1]
基于密钥哈希的消息认证码 (HMAC)。NIST。2008 年 7 月。URL: http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 活标准. URL: https://html.whatwg.cn/multipage/
[Infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[JWA]
JSON Web Algorithms (JWA)。M. Jones。IETF。2015 年 5 月。建议标准。URL: https://www.rfc-editor.org/rfc/rfc7518
[JWK]
JSON Web Key (JWK)。M. Jones。IETF。2015 年 5 月。建议标准。URL: https://www.rfc-editor.org/rfc/rfc7517
[NIST-SP800-38A]
NIST 特别出版物 800-38A:分组密码操作模式建议,方法与技术。NIST。2001 年 12 月。URL:http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
[NIST-SP800-38D]
NIST 特别出版物 800-38D:分组密码操作模式建议:伽罗瓦/计数器模式 (GCM) 和 GMAC。NIST。2007 年 11 月。URL:http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC2141]
URN 语法。R. Moats。IETF。1997 年 5 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc2141
[RFC2315]
PKCS #7:加密消息语法 1.5 版。B. Kaliski。IETF。1998 年 3 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc2315
[RFC3394]
高级加密标准 (AES) 密钥封装算法。J. Schaad; R. Housley。IETF。2002 年 9 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc3394
[RFC3447]
公钥密码标准 (PKCS) #1:RSA 密码规范 2.1 版。J. Jonsson; B. Kaliski。IETF。2003 年 2 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc3447
[RFC4122]
通用唯一标识符 (UUID) URN 命名空间. P. Leach; M. Mealling; R. Salz. IETF. 2005年7月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc4122
[RFC5208]
公钥密码标准 (PKCS) #8:私钥信息语法规范 1.2 版。B. Kaliski。IETF。2008 年 5 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc5208
[RFC5280]
互联网 X.509 公钥基础设施证书和证书撤销列表 (CRL) 配置文件。D. Cooper; S. Santesson; S. Farrell; S. Boeyen; R. Housley; W. Polk。IETF。2008 年 5 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc5280
[RFC5480]
椭圆曲线密码学主体公钥信息。S. Turner; D. Brown; K. Yiu; R. Housley; T. Polk。IETF。2009 年 3 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc5480
[RFC5869]
基于 HMAC 的提取并扩展密钥派生函数 (HKDF)。H. Krawczyk; P. Eronen。IETF。2010 年 5 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc5869
[RFC5915]
椭圆曲线私钥结构。S. Turner; D. Brown。IETF。2010 年 6 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc5915
[RFC6090]
基本椭圆曲线密码算法。D. McGrew; K. Igoe; M. Salter。IETF。2011 年 2 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc6090
[RFC7748]
用于安全的椭圆曲线。A. Langley; M. Hamburg; S. Turner。IETF。2016 年 1 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc7748
[RFC8018]
PKCS #5:基于密码的密码学规范 2.1 版。K. Moriarty, Ed.; B. Kaliski; A. Rusch。IETF。2017 年 1 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc8018
[RFC8032]
爱德华曲线数字签名算法 (EdDSA)。S. Josefsson; I. Liusvaara。IETF。2017 年 1 月。信息类。URL:https://www.rfc-editor.org/rfc/rfc8032
[RFC8037]
JSON 对象签名与加密 (JOSE) 中的 CFRG 椭圆曲线 Diffie-Hellman (ECDH) 和签名。I. Liusvaara。IETF。2017 年 1 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc8037
[RFC8174]
RFC 2119 关键词中大小写的歧义. B. Leiba. IETF. 2017年5月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8410]
用于互联网 X.509 公钥基础设施的 Ed25519、Ed448、X25519 和 X448 的算法标识符。S. Josefsson; J. Schaad。IETF。2018 年 8 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc8410
[SEC1]
SEC 1:椭圆曲线密码学。Certicom Research。URL:http://www.secg.org/sec1-v2.pdf
[WebIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/
[X690]
信息技术 - ASN.1 编码规则:基本编码规则 (BER)、规范编码规则 (CER) 和可辨别编码规则 (DER) 规范。Justin Uberti; Cullen Jennings; Eric Rescorla。ITU-T。2008 年 11 月。ITU-T 建议。URL:https://tools.ietf.org/html/draft-ietf-rtcweb-jsep/

D.2 资料性参考文献

[INDEXEDDB]
索引数据库 API。Nikunj Mehta; Jonas Sicking; Eliot Graff; Andrei Popescu; Jeremy Orlow; Joshua Bell。W3C。2015 年 1 月 8 日。W3C 推荐标准。URL:https://w3org.cn/TR/IndexedDB/