Web 加密 API 中的现代算法

社区组报告草案

最新发布版本:
最新编辑稿:
https://wicg.github.io/webcrypto-modern-algos/
编辑:
Proton AG
Okta
反馈:
GitHub WICG/webcrypto-modern-algos拉取请求新建议题未解决的议题

摘要

本规范为 Web 加密 API 定义了多种后量子安全算法和 现代密码算法,即 ML-KEM、ML-DSA、SLH-DSA、AES-OCB、ChaCha20-Poly1305、 SHA-3、cSHAKE、TurboSHAKE、KangarooTwelve、KMAC 和 Argon2。

本文档状态

本规范由 Web 平台孵化器社区组发布。它不是 W3C 标准,也不处于 W3C 标准流程中。 请注意,根据 W3C 社区贡献者许可协议 (CLA), 退出权受到限制,并且还适用其他条件。 进一步了解 W3C 社区组和商业组

这是一项非官方提案。

建议通过 GitHub 议题 讨论本规范。

1. 简介

本节不具规范性。

本提案旨在使 Web 加密 API 中可用的密码算法集现代化,以便 Web 应用程序能够使用具备后量子安全性且 性能良好的密码算法。 为此,添加以下密码算法:

为了支持 ML-KEM 以及将来可能出现的其他 KEM, 本提案引入了用于密钥封装和解封装的函数: SubtleCrypto.encapsulateKeySubtleCrypto.encapsulateBitsSubtleCrypto.decapsulateKeySubtleCrypto.decapsulateBits

此外,本提案还引入了 SubtleCrypto.getPublicKey 函数, 它提供了一种从非对称私钥派生公钥的便捷方式, 当只需要私钥时,无需分别存储公钥和私钥。

最后,本提案旨在简化特性检测, 方法是添加 SubtleCrypto.supports 函数, 该函数可用于检测指定操作是否支持给定的算法标识符 (包括任何参数)。

2. 规范约定

本规范遵循 [webcrypto] 第 18.3 节中规定的约定。此处定义的算法均 不要求实现,但如果符合规范的用户代理实现了某个 算法,则它必须实现本文档规定的所有受支持操作, 并且必须针对每个受支持的操作,执行 [webcrypto] 第 18.4.3 节中规定的定义算法 步骤。

3. 部分 SubtleCrypto 接口

本节扩展了 [webcrypto] 的 SubtleCrypto 接口。

WebIDL[SecureContext,Exposed=(Window,Worker)]
partial interface SubtleCrypto {
  Promise<EncapsulatedKey> encapsulateKey(
    AlgorithmIdentifier encapsulationAlgorithm,
    CryptoKey encapsulationKey,
    AlgorithmIdentifier sharedKeyAlgorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<EncapsulatedBits> encapsulateBits(
    AlgorithmIdentifier encapsulationAlgorithm,
    CryptoKey encapsulationKey
  );

  Promise<CryptoKey> decapsulateKey(
    AlgorithmIdentifier decapsulationAlgorithm,
    CryptoKey decapsulationKey,
    BufferSource ciphertext,
    AlgorithmIdentifier sharedKeyAlgorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<ArrayBuffer> decapsulateBits(
    AlgorithmIdentifier decapsulationAlgorithm,
    CryptoKey decapsulationKey,
    BufferSource ciphertext
  );

  Promise<CryptoKey> getPublicKey(
    CryptoKey key,
    sequence<KeyUsage> keyUsages
  );

  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   optional unsigned long? length = null);
  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   AlgorithmIdentifier additionalAlgorithm);
};

3.1 数据类型

3.1.1 密钥格式

本规范将 [webcrypto] 中 KeyFormat 的定义替换为以下内容:

WebIDLenum KeyFormat { "raw-public", "raw-private", "raw-seed", "raw-secret", "raw", "spki", "pkcs8", "jwk" };

本规范规定了多个新的已识别密钥格式 值

raw-public
未格式化的公钥字节序列。
raw-private
未格式化的私钥字节序列。
raw-seed
未格式化的私钥种子字节序列。
raw-secret
未格式化的秘密密钥字节序列。

对于 [webcrypto] 中所有现有的对称算法, “raw-secret”作为“raw”的别名。

对于 [webcrypto] 中所有现有的非对称算法, “raw-public”作为“raw”的别名。

deriveKey() 方法的导入密钥步骤中, 必须使用“raw-secret”作为格式, 而不是“raw”。

3.1.2 密钥用途

本规范将 [webcrypto] 中 KeyUsage 的定义替换为以下内容:

WebIDLenum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey", "encapsulateKey", "encapsulateBits", "decapsulateKey", "decapsulateBits" };

本规范规定了多个新的已识别密钥用途 值

encapsulateKey
允许将密钥用于 SubtleCrypto.encapsulateKey
encapsulateBits
允许将密钥用于 SubtleCrypto.encapsulateBits
decapsulateKey
允许将密钥用于 SubtleCrypto.decapsulateKey
decapsulateBits
允许将密钥用于 SubtleCrypto.decapsulateBits

3.2 方法和参数

3.2.1 encapsulateKey 方法

encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages) 方法封装一个密钥,并返回一个 EncapsulatedKey 对象。 其行为如下:

  1. encapsulationAlgorithmencapsulationKeysharedKeyAlgorithmextractableusages 分别为传递给 encapsulateKey() 方法的 encapsulationAlgorithmencapsulationKeysharedKeyAlgorithmextractablekeyUsages 参数。

  2. normalizedEncapsulationAlgorithm规范化 算法的结果,其中 alg 设置为 encapsulationAlgorithmop 设置为 “encapsulate”。

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

  4. normalizedSharedKeyAlgorithm规范化 算法的结果,其中 alg 设置为 sharedKeyAlgorithmop 设置为 “importKey”。

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

  6. realmthis相关 领域

  7. promise 为一个新的 Promise。

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

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

  10. 如果 normalizedEncapsulationAlgorithmname 成员不等于 encapsulationKey[[algorithm]] 内部槽的 name 属性,则抛出一个 InvalidAccessError

  11. 如果 encapsulationKey[[usages]] 内部槽不包含值为“encapsulateKey”的条目, 则抛出一个 InvalidAccessError

  12. encapsulatedBits 为使用 encapsulationKey 执行由 encapsulationKey[[algorithm]] 内部槽指定的封装操作所得的结果。

  13. sharedKey 为执行由 normalizedSharedKeyAlgorithm 指定的导入密钥操作所得的结果,其中使用“raw-secret”作为 format,使用 encapsulatedBitssharedKey 字段作为 keyData,使用 sharedKeyAlgorithm 作为 algorithm,并使用 extractableusages

  14. sharedKey[[extractable]] 内部槽设置为 extractable

  15. sharedKey[[usages]] 内部槽设置为 usages规范化值

  16. encapsulatedKey 为一个新的 EncapsulatedKey 字典, 其中将 sharedKey 设置为 sharedKey, 并将 ciphertext 设置为 encapsulatedBitsciphertext 字段。

  17. 加密任务源上, 给定 realm 的全局对象,排入 一个全局任务,以执行剩余步骤。

  18. result 为按照 [WebIDL] 的定义, 在 realm 中将 encapsulatedKey 转换为 ECMAScript 对象所得的结果。

  19. 使用 result 兑现 promise

3.2.2 encapsulateBits 方法

encapsulateBits(encapsulationAlgorithm, encapsulationKey) 方法封装一个密钥,并返回一个 EncapsulatedBits 对象。 其行为如下:

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

  2. normalizedEncapsulationAlgorithm规范化 算法的结果,其中 alg 设置为 encapsulationAlgorithmop 设置为 “encapsulate”。

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

  4. realmthis相关 领域

  5. promise 为一个新的 Promise。

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

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

  8. 如果 normalizedEncapsulationAlgorithmname 成员不等于 encapsulationKey[[algorithm]] 内部槽的 name 属性,则抛出一个 InvalidAccessError

  9. 如果 encapsulationKey[[usages]] 内部槽不包含值为 “encapsulateBits”的条目, 则抛出一个 InvalidAccessError

  10. encapsulatedBits 为使用 encapsulationKey 执行由 encapsulationKey[[algorithm]] 内部槽指定的封装操作所得的结果。

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

  12. result 为按照 [WebIDL] 的定义, 在 realm 中将 encapsulatedBits 转换为 ECMAScript 对象所得的结果。

  13. 使用 result 兑现 promise

3.2.3 decapsulateKey 方法

decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages) 方法解封装一个密钥,并返回一个 CryptoKey 对象。 其行为如下:

  1. decapsulationAlgorithmdecapsulationKeysharedKeyAlgorithmextractableusages 分别为传递给 decapsulateKey() 方法的 decapsulationAlgorithmdecapsulationKeysharedKeyAlgorithmextractablekeyUsages 参数。

  2. normalizedDecapsulationAlgorithm规范化 算法的结果,其中 alg 设置为 decapsulationAlgorithmop 设置为 “decapsulate”。

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

  4. normalizedSharedKeyAlgorithm规范化 算法的结果,其中 alg 设置为 sharedKeyAlgorithmop 设置为 “importKey”。

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

  6. ciphertext 为对传递给 decapsulateKey() 方法的 ciphertext 参数所持有的字节创建副本所得的结果。

  7. realmthis相关 领域

  8. promise 为一个新的 Promise。

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

  10. 如果以下步骤或引用的过程要求 抛出错误, 则在加密任务源上, 给定 realm 的全局对象,排入一个全局任务, 以使用返回的错误拒绝 promise; 然后终止 算法

  11. 如果 normalizedDecapsulationAlgorithmname 成员不等于 decapsulationKey[[algorithm]] 内部槽的 name 属性,则抛出一个 InvalidAccessError

  12. 如果 decapsulationKey[[usages]] 内部槽不包含值为“decapsulateKey”的条目, 则抛出一个 InvalidAccessError

  13. decapsulatedBits 为使用 decapsulationKeyciphertext 执行由 decapsulationKey[[algorithm]] 内部槽指定的解封装操作所得的结果。

  14. sharedKey 为执行由 normalizedSharedKeyAlgorithm 指定的导入密钥操作所得的结果,其中使用“raw-secret”作为 format,使用 decapsulatedBits 作为 keyData, 使用 sharedKeyAlgorithm 作为 algorithm,并使用 extractableusages

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

  16. sharedKey[[usages]] 内部槽设置为 usages规范化值

  17. 加密任务源上, 给定 realm 的全局对象,排入 一个全局任务,以执行剩余步骤。

  18. result 为按照 [WebIDL] 的定义, 在 realm 中将 sharedKey 转换为 ECMAScript 对象所得的结果。

  19. 使用 result 兑现 promise

3.2.4 decapsulateBits 方法

decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext) 方法解封装一个密钥,并返回一个 ArrayBuffer 对象。 其行为如下:

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

  2. normalizedDecapsulationAlgorithm规范化 算法的结果,其中 alg 设置为 decapsulationAlgorithmop 设置为 “decapsulate”。

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

  4. ciphertext 为对传递给 decapsulateBits() 方法的 ciphertext 参数所持有的字节创建副本所得的结果。

  5. realmthis相关 领域

  6. promise 为一个新的 Promise。

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

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

  9. 如果 normalizedDecapsulationAlgorithmname 成员不等于 decapsulationKey[[algorithm]] 内部槽的 name 属性,则抛出一个 InvalidAccessError

  10. 如果 decapsulationKey[[usages]] 内部槽不包含值为 “decapsulateBits”的条目, 则抛出一个 InvalidAccessError

  11. decapsulatedBits 为使用 decapsulationKeyciphertext 执行由 decapsulationKey[[algorithm]] 内部槽指定的解封装操作所得的结果。

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

  13. result 为在 realm创建一个 包含 decapsulatedBitsArrayBuffer 所得的结果。

  14. 使用 result 兑现 promise

3.2.5 getPublicKey 方法

getPublicKey(key, usages) 方法返回与给定私钥对应的公钥。 其行为如下:

  1. keyusages 分别为传递给 getPublicKey() 方法的 keykeyUsages 参数。

  2. algorithmkey[[algorithm]] 内部槽。

  3. 如果由 algorithm 标识的密码算法 不支持从私钥派生公钥, 则返回一个以 NotSupportedError 拒绝的 Promise。

  4. realmthis相关 领域

  5. promise 为一个新的 Promise。

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

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

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

  9. 如果 usages 包含由 algorithm 标识的算法 不支持用于公钥的条目, 则抛出一个 SyntaxError

  10. publicKey 为一个新的 CryptoKey, 它表示与 key[[handle]] 内部槽所表示的私钥对应的公钥。

  11. 如果发生错误,则抛出一个 OperationError

  12. publicKey[[type]] 内部槽设置为“public”。

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

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

  15. publicKey[[usages]] 内部槽设置为 usages

  16. 加密任务源上, 给定 realm 的全局对象,排入 一个全局任务,以执行剩余步骤。

  17. result 为按照 [WebIDL] 的定义, 在 realm 中将 publicKey 转换为 ECMAScript 对象所得的结果。

  18. 使用 result 兑现 promise

3.2.6 supports 方法

supports(operation, algorithm, length) 方法返回一个布尔值,指示实现是否支持 使用指定的 AlgorithmIdentifier 执行给定操作,并可选地使用 length 参数, 在 operation 为“deriveBits”时指示要派生的比特数。 其行为如下:

  1. 如果 operation 不是 “encrypt”、“decrypt”、“sign”、“verify”、 “digest”、“generateKey”、“deriveKey”、 “deriveBits”、 “importKey”、“exportKey”、“wrapKey”、 “unwrapKey”、 “encapsulateKey”、“encapsulateBits”、 “decapsulateKey”、“decapsulateBits”或 “getPublicKey”之一, 则返回 false。

  2. 返回检查对 算法的支持所得的结果, 其中 op 设置为 operationalg 设置为 algorithmlength 设置为 length

supports(operation, algorithm, additionalAlgorithm) 方法返回一个布尔值,指示实现是否支持 使用指定的 AlgorithmIdentifier 执行给定操作。 当 operation 为 “deriveKey”时,附加算法指示要派生的密钥类型; 当 operation 为 “wrapKey”时,指示包装前要导出的密钥类型; 当 operation 为 “unwrapKey”时,指示解包后要导入的密钥类型。 其行为如下:

  1. 如果 operation 不是 “encrypt”、“decrypt”、“sign”、“verify”、 “digest”、“generateKey”、“deriveKey”、 “deriveBits”、 “importKey”、“exportKey”、“wrapKey”、 “unwrapKey”、 “encapsulateKey”、“encapsulateBits”、 “decapsulateKey”、“decapsulateBits”或 “getPublicKey”之一, 则返回 false。

  2. 如果 operation 是“deriveKey”、“unwrapKey”、 “encapsulateKey”或“decapsulateKey”:

    如果检查 对算法的支持所得的结果为 false, 其中 op 设置为“importKey”, alg 设置为 additionalAlgorithm, 则返回 false。

    如果 operation 是“wrapKey”:

    如果检查 对算法的支持所得的结果为 false, 其中 op 设置为“exportKey”, alg 设置为 additionalAlgorithm, 则返回 false。

  3. length 为 null。

  4. 如果 operation 是“deriveKey”:
    1. 如果检查对 算法的支持所得的结果为 false, 其中 op 设置为“get key length”, alg 设置为 additionalAlgorithm, 则返回 false。

    2. normalizedAdditionalAlgorithm规范化 算法的结果,其中 alg 设置为 additionalAlgorithmop 设置为 “get key length”。

    3. length 为使用 normalizedAdditionalAlgorithm 执行由 additionalAlgorithm 指定的获取密钥长度算法所得的结果。

    4. operation 设置为“deriveBits”。

  5. 返回检查对 算法的支持所得的结果, 其中 op 设置为 operationalg 设置为 algorithmlength 设置为 length

3.3 检查对 算法的支持

检查对算法的支持算法 定义了一个过程,用于检查给定操作是否支持给定算法。 其输入是操作名称 op、一个 AlgorithmIdentifier alg 和一个 length 参数。其输出是一个布尔值。 其行为如下:

  1. 如果 op 是“encapsulateKey”或“encapsulateBits”,则将 op 设置为“encapsulate”。

  2. 如果 op 是“decapsulateKey”或“decapsulateBits”,则将 op 设置为“decapsulate”。

  3. 如果 op 是“getPublicKey”:
    1. normalizedAlgorithm规范化 算法的结果,其中 alg 设置为 algop 设置为 “exportKey”。

    2. 如果发生错误,则返回 false。

    3. 如果由 normalizedAlgorithm 标识的密码算法 不支持从私钥派生公钥, 则返回 false。

    4. 否则,返回 true。

  4. normalizedAlgorithm规范化 算法的结果,其中 alg 设置为 algop 设置为 op

  5. 如果发生错误:
    1. 如果 op 是“wrapKey”, 则返回检查对 算法的支持所得的结果, 其中 op 设置为“encrypt”, alg 设置为 alg

    2. 如果 op 是“unwrapKey”, 则返回检查对 算法的支持所得的结果, 其中 op 设置为“decrypt”, alg 设置为 alg

    3. 否则,返回 false。

  6. 如果由于特定于实现的原因 (例如已知不符合规范),预期指定操作或算法(或其某个参数值) 会失败(对于任何密钥和/或数据),则返回 false。

  7. 如果 op 是“generateKey”或“importKey”,则令 usages 为空列表。

  8. 对于由 normalizedAlgorithm 指定的算法中, 由 op 指定的操作的每个步骤:

    如果该步骤要求抛出错误:
    返回 false。
    如果该步骤要求生成密钥:
    返回 true。
    如果该步骤依赖不可用的参数,例如 keyplaintextciphertext
    返回 true。
    如果该步骤要求返回一个值:
    返回 true。
    否则:
    执行该步骤。

    所引用算法中的步骤可以访问此上下文中的 normalizedAlgorithmlengthusages 变量。

  9. 断言:永远不会到达此步骤, 因为该操作的某个步骤必然已经要求 返回一个值或抛出错误,从而使我们分别返回 true 或 false。

4. 封装字典

WebIDLdictionary EncapsulatedKey {
  CryptoKey sharedKey;
  ArrayBuffer ciphertext;
};

dictionary EncapsulatedBits {
  ArrayBuffer sharedKey;
  ArrayBuffer ciphertext;
};

EncapsulatedKey 字典表示一个 由 sharedKey 和一个 ciphertext 组成的封装密钥。

EncapsulatedBits 字典表示 由 sharedKey 和一个 ciphertext 组成的封装密钥比特。

5. 部分 JsonWebKey 字典

WebIDLpartial dictionary JsonWebKey {
  // 以下字段在 RFC 9964 中定义
  DOMString pub;
  DOMString priv;
};

[webcrypto] 中定义的 JsonWebKey 字典的此扩展, 提供了一种表示具有 [RFC9964] 中定义的“AKP”密钥类型的密钥的方法。

6. ML-KEM

6.1 描述

本节不具规范性。

本节描述了如何按照 [FIPS-203] 的规定, 使用 ML-KEM 进行密钥封装和解封装。

6.2 注册

此算法的已识别算法 名称为 “ML-KEM-512”、“ML-KEM-768”和“ML-KEM-1024”。

操作 参数 结果
encapsulate EncapsulatedBits
decapsulate 字节 序列
generateKey CryptoKeyPair
importKey CryptoKey
exportKey 对象

6.3 操作

6.3.1 封装

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

  2. 使用由 algorithmname 成员指示的参数集,执行 [FIPS-203] 第 7.2 节中所述的封装密钥检查, 并使用 key[[handle]] 内部槽所表示的密钥作为 ek 输入参数。

    如果有利于性能,可以为 CryptoKey 对象缓存或预先计算此检查的结果。

  3. 如果封装密钥检查失败,则返回一个 OperationError

  4. sharedKeyciphertext 为执行 [FIPS-203] 第 7.2 节中所述的 ML-KEM.Encaps 函数所得的输出, 其中使用由 algorithmname 成员指示的参数集, 并使用 key[[handle]] 内部槽所表示的密钥作为 ek 输入参数。

  5. 如果 ML-KEM.Encaps 函数返回错误,则返回一个 OperationError

  6. result 为一个新的 EncapsulatedBits 字典。

  7. resultsharedKey 属性 设置为创建一个 包含 sharedKeyArrayBuffer 所得的结果。

  8. resultciphertext 属性 设置为创建一个 包含 ciphertextArrayBuffer 所得的结果。

  9. 返回 result

6.3.2 解封装

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

  2. 使用由 algorithmname 成员指示的参数集,执行 [FIPS-203] 第 7.3 节中所述的解封装输入检查, 并使用 key[[handle]] 内部槽所表示的密钥作为 dk 输入参数, 使用 ciphertext 作为 c 输入参数。

    如果有利于性能,可以为 CryptoKey 对象缓存或预先计算解封装密钥类型检查和哈希检查的结果。

  3. 如果解封装密钥检查失败,则返回一个 OperationError

  4. sharedKey 为执行 [FIPS-203] 第 7.3 节中所述的 ML-KEM.Decaps 函数所得的输出, 其中使用由 algorithmname 成员指示的参数集, 并使用 key[[handle]] 内部槽所表示的密钥作为 dk 输入参数, 使用 ciphertext 作为 c 输入参数。

  5. 返回 sharedKey

6.3.3 生成密钥

  1. 如果 usages 包含不是 “encapsulateKey”、“encapsulateBits”、 “decapsulateKey”或“decapsulateBits” 之一的条目,则抛出一个 SyntaxError

  2. 按照 [FIPS-203] 第 7.1 节中的描述生成一个 ML-KEM 密钥对, 其中使用由 normalizedAlgorithmname 成员指示的参数集。

    为了能够导出种子 (d, z), 需要将 dz 作为生成的 密钥材料的一部分存储。

  3. 如果密钥生成步骤失败, 则抛出一个 OperationError

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

  5. algorithmname 属性设置为 normalizedAlgorithmname 属性。

  6. publicKey 为一个新的 CryptoKey, 它表示所生成密钥对的封装密钥。

  7. publicKey[[type]] 内部槽设置为“public”。

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

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

  10. publicKey[[usages]] 内部槽设置为 usages[ "encapsulateKey", "encapsulateBits" ]用途 交集

  11. privateKey 为一个新的 CryptoKey, 它表示所生成密钥对的解封装密钥。

  12. privateKey[[type]] 内部槽设置为“private”。

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

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

  15. privateKey[[usages]] 内部槽设置为 usages[ "decapsulateKey", "decapsulateBits" ]用途 交集

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

  17. resultpublicKey 属性设置为 publicKey

  18. resultprivateKey 属性设置为 privateKey

  19. 返回 result

6.3.4 导入密钥

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

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

    2. spki 为在 keyData 上运行 解析 subjectPublicKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是“ML-KEM-512”:

      expectedOidid-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1)。

      如果 normalizedAlgorithmname 成员是“ML-KEM-768”:

      expectedOidid-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2)。

      如果 normalizedAlgorithmname 成员是“ML-KEM-1024”:

      expectedOidid-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3)。

      否则:

      抛出一个 NotSupportedError

    5. 如果 spkialgorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段 不等于 expectedOid, 则抛出一个 DataError

    6. 如果 spkialgorithm AlgorithmIdentifier 字段中存在 parameters 字段, 则抛出一个 DataError

    7. publicKey 为由 spkisubjectPublicKey 字段标识的 ML-KEM 公钥。

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

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

    10. algorithm 为一个新的 KeyAlgorithm

    11. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

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

    2. privateKeyInfo 为在 keyData 上运行 解析 privateKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是“ML-KEM-512”:

      expectedOidid-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1)。

      asn1Structure 为 ASN.1 ML-KEM-512-PrivateKey 结构。

      如果 normalizedAlgorithmname 成员是“ML-KEM-768”:

      expectedOidid-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2)。

      asn1Structure 为 ASN.1 ML-KEM-768-PrivateKey 结构。

      如果 normalizedAlgorithmname 成员是“ML-KEM-1024”:

      expectedOidid-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3)。

      asn1Structure 为 ASN.1 ML-KEM-1024-PrivateKey 结构。

      否则:

      抛出一个 NotSupportedError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 expectedOid, 则抛出一个 DataError

    6. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段中 存在 parameters 字段, 则抛出一个 DataError

    7. mlKemPrivateKey 为执行 解析 ASN.1 结构 算法所得的结果,其中将 privateKeyInfoprivateKey 字段用作 data, 将 asn1Structure 用作 structure, 并将 exactData 设置为 true。

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

    9. 如果 mlKemPrivateKey 表示采用 expandedKey 格式的 ML-KEM 密钥, 或者 mlKemPrivateKey 表示采用 both 格式的 ML-KEM 密钥 且不支持 both 格式,则抛出一个 NotSupportedError

    10. 如果 mlKemPrivateKey 表示采用 both 格式的 ML-KEM 密钥, 且 seed 字段与 expandedKey 字段不对应, 则抛出一个 DataError

    11. key 为一个新的 CryptoKey, 它表示由 mlKemPrivateKey 标识的 ML-KEM 私钥。

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

    13. algorithm 为一个新的 KeyAlgorithm

    14. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

    如果 format 是“raw-public”:
    1. 如果 usages 包含不是 “encapsulateKey”或“encapsulateBits”的条目, 则抛出一个 SyntaxError

    2. datakeyData

    3. key 为一个新的 CryptoKey, 它表示 data 中的 ML-KEM 公钥数据。

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

    5. algorithm 为一个新的 KeyAlgorithm

    6. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

    如果 format 是“raw-seed”:
    1. 如果 usages 包含不是 “decapsulateKey”或“decapsulateBits”的条目, 则抛出一个 SyntaxError

    2. datakeyData

    3. 如果 data 的比特长度不是 512, 则抛出一个 DataError

    4. privateKey 为执行 [FIPS-203] 第 6.1 节中所述的 ML-KEM.KeyGen_internal 函数所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 并使用 data 的前 256 比特作为 d, 使用 data 的后 256 比特作为 z

    5. key 为一个新的 CryptoKey, 它表示由 privateKey 标识的 ML-KEM 私钥。

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

    7. algorithm 为一个新的 KeyAlgorithm

    8. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

    如果 format 是“jwk”:
    议题 1

    ML-KEM 的 JWK 格式尚未标准化,因此可能会发生变化。

    1. 如果 keyData 是一个 JsonWebKey 字典:

      jwk 等于 keyData

      否则:

      抛出一个 DataError

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

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

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

    5. 如果 jwkalg 字段不是 [draft-ietf-jose-pqc-kem-05] 第 8 节(图 1 或图 2)中所示的、与 normalizedAlgorithmname 成员对应的 alg 值之一, 则抛出一个 DataError

      例如,ML-KEM-512ML-KEM-512+A128KW 是 ML-KEM-512 的有效“alg”值。

    6. 如果 usages 非空,且 jwk 中存在 use 字段, 并且该字段不等于“enc”,则抛出一个 DataError

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

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

    9. 如果 jwk 中存在 priv 字段:
      1. 如果 jwkpriv 属性不包含表示 ML-KEM 私钥的有效 base64url 编码种子, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpriv 属性解释为 base64url 编码种子所标识的 ML-KEM 私钥。

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

      4. 如果 jwkpub 属性不包含表示与 key 对应的 ML-KEM 公钥的 base64url 编码公钥, 则抛出 一个 DataError

      否则:
      1. 如果 jwkpub 属性不包含表示 ML-KEM 公钥的有效 base64url 编码公钥, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpub 属性解释为 base64url 编码公钥所标识的 ML-KEM 公钥。

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

    10. algorithm 为一个新的 KeyAlgorithm 对象实例。

    11. algorithmname 属性设置为 normalizedAlgorithmname 成员。

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

    否则:
    抛出一个 NotSupportedError
  3. 返回 key

6.3.5 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

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

        • 如果 keyAlgorithmname 成员是 “ML-KEM-512”:

          algorithm 对象标识符设置为 id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1) OID。

          如果 keyAlgorithmname 成员是 “ML-KEM-768”:

          algorithm 对象标识符设置为 id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2) OID。

          如果 keyAlgorithmname 成员是 “ML-KEM-1024”:

          algorithm 对象标识符设置为 id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3) OID。

          否则:

          抛出 一个 NotSupportedError

      • subjectPublicKey 字段设置为 keyData

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

      • version 字段设置为 0

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

        • 如果 keyAlgorithmname 成员是 “ML-KEM-512”:

          algorithm 对象标识符设置为 id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1) OID。

          如果 keyAlgorithmname 成员是 “ML-KEM-768”:

          algorithm 对象标识符设置为 id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2) OID。

          如果 keyAlgorithmname 成员是 “ML-KEM-1024”:

          algorithm 对象标识符设置为 id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3) OID。

          否则:

          抛出 一个 NotSupportedError

      • 按如下方式设置 privateKey 字段:

        • 如果 keyAlgorithmname 成员是 “ML-KEM-512”:

          privateKey 字段设置为 对一个 ML-KEM-512-PrivateKey ASN.1 类型进行 DER 编码所得的结果,该类型使用仅种子 格式表示由 key[[handle]] 内部槽所表示的 ML-KEM 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          如果 keyAlgorithmname 成员是 “ML-KEM-768”:

          privateKey 字段设置为 对一个 ML-KEM-768-PrivateKey ASN.1 类型进行 DER 编码所得的结果,该类型使用仅种子 格式表示由 key[[handle]] 内部槽所表示的 ML-KEM 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          如果 keyAlgorithmname 成员是 “ML-KEM-1024”:

          privateKey 字段设置为 对一个 ML-KEM-1024-PrivateKey ASN.1 类型进行 DER 编码所得的结果, 该类型使用仅种子格式表示由 key[[handle]] 内部槽所表示的 ML-KEM 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          否则:

          抛出 一个 NotSupportedError

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. data 为一个字节序列, 其中包含 key[[handle]] 内部槽所表示的密钥的原始八位字节。

    3. resultdata

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

    2. data 为一个字节序列, 其中包含 key[[handle]] 内部槽所表示的密钥的 dz 种子变量的串联。

      dz 种子变量是在 ML-KEM.KeyGen 函数中采样的, 如 [FIPS-203] 第 7.1 节所述。

    3. resultdata

    如果 format 是“jwk”:
    议题 2

    ML-KEM 的 JWK 格式尚未标准化,因此可能会发生变化。

    1. jwk 为一个新的 JsonWebKey 字典。

    2. keyAlgorithmkey[[algorithm]] 内部槽。

    3. jwkkty 属性设置为 “AKP”。

    4. jwkalg 属性设置为 [draft-ietf-jose-pqc-kem-05] 第 8 节(图 1)中所示的、与 keyAlgorithmname 成员对应的 alg 值。

      例如,ML-KEM-512 是用于 ML-KEM-512 的“alg”值。

    5. jwkpub 属性 设置为与 key[[handle]] 内部槽对应的 base64url 编码公钥。

    6. 如果 key[[type]] 内部槽是“private”:
      jwkpriv 属性 设置为由 key[[handle]] 内部槽所表示的 base64url 编码种子。
    7. jwkkey_ops 属性设置为 keyusages 属性。

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

    9. resultjwk

    否则:

    抛出一个 NotSupportedError

  4. 返回 result

7. ML-DSA

7.1 描述

本节不具规范性。

本节描述了如何按照 [FIPS-204] 的规定, 使用 ML-DSA 进行签名和验证。

7.2 注册

此算法的已识别算法 名称为 “ML-DSA-44”、“ML-DSA-65”和“ML-DSA-87”。

操作 参数 结果
sign ContextParams 字节 序列
verify ContextParams 布尔值
generateKey CryptoKeyPair
importKey CryptoKey
exportKey 对象

7.3 ContextParams 字典

WebIDLdictionary ContextParams : Algorithm {
  BufferSource context;
};

context 成员表示要与消息 关联的可选上下文数据。

ContextParams 字典与 [webcrypto-secure-curves] 的 Ed448Params 字典相同,在合并本提案时,后者可以由前者替代。

7.4 操作

7.4.1 签名

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

  2. 如果 normalizedAlgorithm 中存在 context 成员,则令 context 为该成员; 否则,令其为空八位字节字符串。

  3. result 为执行 [FIPS-204] 第 5.2 节中规定的 ML-DSA.Sign 签名算法所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 使用与 key 关联的 ML-DSA 私钥作为 sk, 使用 message 作为 M,并使用 context 作为 ctx

  4. 如果 ML-DSA.Sign 算法返回错误,则返回一个 OperationError

  5. 返回 result

7.4.2 验证

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

  2. 如果 normalizedAlgorithm 中存在 context 成员,则令 context 为该成员; 否则,令其为空八位字节字符串。

  3. result 为执行 [FIPS-204] 第 5.3 节中规定的 ML-DSA.Verify 验证算法所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 使用与 key 关联的 ML-DSA 公钥作为 pk, 使用 message 作为 M,使用 signature 作为 σ,并 使用 context 作为 ctx

  4. 如果 ML-DSA.Verify 算法返回错误,则返回一个 OperationError

  5. 返回 result

7.4.3 生成密钥

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

  2. 按照 [FIPS-204] 第 5.1 节中的描述生成一个 ML-DSA 密钥对,其中使用 由 normalizedAlgorithmname 成员指示的参数集。

    为了能够导出种子 ξ, 需要将其作为生成的 密钥材料的一部分存储。

  3. 如果密钥生成步骤失败, 则抛出一个 OperationError

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

  5. algorithmname 属性设置为 normalizedAlgorithmname 属性。

  6. publicKey 为一个新的 CryptoKey, 它表示所生成密钥对的公钥。

  7. publicKey[[type]] 内部槽设置为“public”。

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

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

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

  11. privateKey 为一个新的 CryptoKey, 它表示所生成密钥对的私钥。

  12. privateKey[[type]] 内部槽设置为“private”。

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

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

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

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

  17. resultpublicKey 属性设置为 publicKey

  18. resultprivateKey 属性设置为 privateKey

  19. 返回 result

7.4.4 导入密钥

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

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

    2. spki 为在 keyData 上运行 解析 subjectPublicKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是“ML-DSA-44”:

      expectedOidid-ml-dsa-44 (2.16.840.1.101.3.4.3.17)。

      如果 normalizedAlgorithmname 成员是“ML-DSA-65”:

      expectedOidid-ml-dsa-65 (2.16.840.1.101.3.4.3.18)。

      如果 normalizedAlgorithmname 成员是“ML-DSA-87”:

      expectedOidid-ml-dsa-87 (2.16.840.1.101.3.4.3.19)。

      否则:

      抛出一个 NotSupportedError

    5. 如果 spkialgorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段 不等于 expectedOid, 则抛出一个 DataError

    6. 如果 spkialgorithm AlgorithmIdentifier 字段中存在 parameters 字段, 则抛出一个 DataError

    7. publicKey 为由 spkisubjectPublicKey 字段标识的 ML-DSA 公钥。

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

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

    10. algorithm 为一个新的 KeyAlgorithm

    11. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

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

    2. privateKeyInfo 为在 keyData 上运行 解析 privateKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是“ML-DSA-44”:

      expectedOidid-ml-dsa-44 (2.16.840.1.101.3.4.3.17)。

      asn1Structure 为 ASN.1 ML-DSA-44-PrivateKey 结构。

      如果 normalizedAlgorithmname 成员是“ML-DSA-65”:

      expectedOidid-ml-dsa-65 (2.16.840.1.101.3.4.3.18)。

      asn1Structure 为 ASN.1 ML-DSA-65-PrivateKey 结构。

      如果 normalizedAlgorithmname 成员是“ML-DSA-87”:

      expectedOidid-ml-dsa-87 (2.16.840.1.101.3.4.3.19)。

      asn1Structure 为 ASN.1 ML-DSA-87-PrivateKey 结构。

      否则:

      抛出一个 NotSupportedError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 expectedOid, 则抛出一个 DataError

    6. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段中 存在 parameters 字段, 则抛出一个 DataError

    7. mlDsaPrivateKey 为执行 解析 ASN.1 结构 算法所得的结果,其中将 privateKeyInfoprivateKey 字段用作 data, 将 asn1Structure 用作 structure,并将 exactData 设置为 true。

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

    9. 如果 mlDsaPrivateKey 表示采用 expandedKey 格式的 ML-DSA 密钥, 或者 mlDsaPrivateKey 表示采用 both 格式的 ML-DSA 密钥 且不支持 both 格式,则抛出一个 NotSupportedError

    10. 如果 mlDsaPrivateKey 表示采用 both 格式的 ML-DSA 密钥, 且 seed 字段与 expandedKey 字段不对应, 则抛出一个 DataError

    11. key 为一个新的 CryptoKey, 它表示由 mlDsaPrivateKey 标识的 ML-DSA 私钥。

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

    13. algorithm 为一个新的 KeyAlgorithm

    14. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

    如果 format 是“raw-public”:
    1. 如果 usages 包含不是 “verify”的条目, 则抛出一个 SyntaxError

    2. algorithm 为一个新的 KeyAlgorithm 对象。

    3. algorithmname 属性设置为 normalizedAlgorithmname 属性。

    4. key 为一个新的 CryptoKey, 它表示 keyData 中提供的密钥数据。

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

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

    如果 format 是“raw-seed”:
    1. 如果 usages 包含不是 “sign”的条目, 则抛出一个 SyntaxError

    2. datakeyData

    3. 如果 data 的比特长度不是 256, 则抛出一个 DataError

    4. privateKey 为执行 [FIPS-204] 第 6.1 节中所述的 ML-DSA.KeyGen_internal 函数所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 并使用 data 作为 ξ

    5. key 为一个新的 CryptoKey, 它表示由 privateKey 标识的 ML-DSA 私钥。

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

    7. algorithm 为一个新的 KeyAlgorithm

    8. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

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

      jwk 等于 keyData

      否则:

      抛出一个 DataError

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

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

    4. 如果 jwkalg 字段不等于 normalizedAlgorithmname 成员, 则抛出一个 DataError

    5. 如果 usages 非空,且 jwk 中存在 use 字段, 并且该字段不等于“sig”,则抛出一个 DataError

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

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

    8. 如果 jwk 中存在 priv 字段:
      1. 如果 jwkpriv 属性不包含表示 ML-DSA 私钥的 有效 base64url 编码种子, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpriv 属性解释为 base64url 编码种子所标识的 ML-DSA 私钥。

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

      4. 如果 jwkpub 属性不包含表示与 key 对应的 ML-DSA 公钥的 base64url 编码公钥, 则抛出 一个 DataError

      否则:
      1. 如果 jwkpub 属性不包含表示 ML-DSA 公钥的 有效 base64url 编码公钥, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpub 属性解释为 base64url 编码公钥所标识的 ML-DSA 公钥。

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

    9. algorithm 为一个新的 KeyAlgorithm 对象实例。

    10. algorithmname 属性设置为 normalizedAlgorithmname 成员。

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

    否则:

    抛出一个 NotSupportedError

  3. 返回 key

7.4.5 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

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

        • 如果 keyAlgorithmname 成员是 “ML-DSA-44”:

          algorithm 对象标识符设置为 id-ml-dsa-44 (2.16.840.1.101.3.4.3.17) OID。

          如果 keyAlgorithmname 成员是 “ML-DSA-65”:

          algorithm 对象标识符设置为 id-ml-dsa-65 (2.16.840.1.101.3.4.3.18) OID。

          如果 keyAlgorithmname 成员是 “ML-DSA-87”:

          algorithm 对象标识符设置为 id-ml-dsa-87 (2.16.840.1.101.3.4.3.19) OID。

          否则:

          抛出 一个 NotSupportedError

      • subjectPublicKey 字段设置为 keyData

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

      • version 字段设置为 0

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

        • 如果 keyAlgorithmname 成员是 “ML-DSA-44”:

          algorithm 对象标识符设置为 id-ml-dsa-44 (2.16.840.1.101.3.4.3.17) OID。

          如果 keyAlgorithmname 成员是 “ML-DSA-65”:

          algorithm 对象标识符设置为 id-ml-dsa-65 (2.16.840.1.101.3.4.3.18) OID。

          如果 keyAlgorithmname 成员是 “ML-DSA-87”:

          algorithm 对象标识符设置为 id-ml-dsa-87 (2.16.840.1.101.3.4.3.19) OID。

          否则:

          抛出 一个 NotSupportedError

      • 按如下方式设置 privateKey 字段:

        • 如果 keyAlgorithmname 成员是 “ML-DSA-44”:

          privateKey 字段设置为 对一个 ML-DSA-44-PrivateKey ASN.1 类型进行 DER 编码所得的结果,该类型使用仅种子 格式表示由 key[[handle]] 内部槽所表示的 ML-DSA 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          如果 keyAlgorithmname 成员是 “ML-DSA-65”:

          privateKey 字段设置为 对一个 ML-DSA-65-PrivateKey ASN.1 类型进行 DER 编码所得的结果,该类型使用仅种子 格式表示由 key[[handle]] 内部槽所表示的 ML-DSA 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          如果 keyAlgorithmname 成员是 “ML-DSA-87”:

          privateKey 字段设置为 对一个 ML-DSA-87-PrivateKey ASN.1 类型进行 DER 编码所得的结果,该类型使用仅种子 格式表示由 key[[handle]] 内部槽所表示的 ML-DSA 私钥种子 (使用上下文特定的 [0] 原始标签,并对 OCTET STRING 进行隐式编码)。

          否则:

          抛出 一个 NotSupportedError

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. data 为一个字节序列, 其中包含由 key[[handle]] 内部槽所表示的 ML-DSA 公钥。

    3. resultdata

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

    2. data 为一个字节序列, 其中包含由 key[[handle]] 内部槽所表示的密钥的 ξ 种子变量。

      ξ 种子变量是在 ML-DSA.KeyGen 函数中采样的, 如 [FIPS-204] 第 5.1 节所述。

    3. resultdata

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

    3. jwkkty 属性设置为 “AKP”。

    4. jwkalg 属性设置为 keyAlgorithmname 成员。

    5. jwkpub 属性 设置为与 key[[handle]] 内部槽对应的 base64url 编码公钥。

    6. 如果 key[[type]] 内部槽是“private”:
      jwkpriv 属性 设置为由 key[[handle]] 内部槽所表示的 base64url 编码种子。
    7. jwkkey_ops 属性设置为 keyusages 属性。

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

    9. resultjwk

    否则:

    抛出一个 NotSupportedError

  4. 返回 result

8. SLH-DSA

8.1 描述

本节不具规范性。

本节描述了如何按照 [FIPS-205] 的规定, 使用 SLH-DSA 进行签名和验证。

8.2 注册

此算法的已识别算法 名称为“SLH-DSA-SHA2-128s”、“SLH-DSA-SHAKE-128s”、 “SLH-DSA-SHA2-128f”、“SLH-DSA-SHAKE-128f”、 “SLH-DSA-SHA2-192s”、“SLH-DSA-SHAKE-192s”、 “SLH-DSA-SHA2-192f”、“SLH-DSA-SHAKE-192f”、 “SLH-DSA-SHA2-256s”、“SLH-DSA-SHAKE-256s”、 “SLH-DSA-SHA2-256f”和“SLH-DSA-SHAKE-256f”。

操作 参数 结果
sign ContextParams 字节 序列
verify ContextParams 布尔值
generateKey CryptoKeyPair
importKey CryptoKey
exportKey 对象

8.3 JSON Web Key 表示形式

SLH-DSA 密钥使用 [RFC9964] 中定义的“AKP”(算法密钥对)密钥类型进行 JWK 表示。“alg”(算法)参数标识具体的 SLH-DSA 参数集。 公钥包含在“pub”参数中。如果包含私钥,则使用“priv”参数表示。以 JWK 表示时,所有密钥参数均采用 base64url 编码。

8.4 操作

8.4.1 签名

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

  2. 如果 normalizedAlgorithm 中存在 context 成员,则令 context 为该成员; 否则,令其为空八位字节字符串。

  3. result 为执行 [FIPS-205] 第 10.2.1 节中规定的 slh_sign 签名算法所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 使用与 key 关联的 SLH-DSA 私钥作为 SK, 使用 message 作为 M,并使用 context 作为 ctx

  4. 如果 slh_sign 算法返回错误,则返回一个 OperationError

  5. 返回 result

8.4.2 验证

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

  2. 如果 normalizedAlgorithm 中存在 context 成员,则令 context 为该成员; 否则,令其为空八位字节字符串。

  3. result 为执行 [FIPS-205] 第 10.3 节中规定的 slh_verify 验证算法所得的结果, 其中使用由 normalizedAlgorithmname 成员指示的参数集, 使用与 key 关联的 SLH-DSA 公钥作为 PK, 使用 message 作为 M,使用 signature 作为 SIG,并 使用 context 作为 ctx

  4. 如果 slh_verify 算法返回错误,则返回一个 OperationError

  5. 返回 result

8.4.3 生成密钥

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

  2. 按照 [FIPS-205] 第 10.1 节中的描述生成一个 SLH-DSA 密钥对,其中使用 由 normalizedAlgorithmname 成员指示的参数集。

  3. 如果密钥生成步骤失败, 则抛出一个 OperationError

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

  5. algorithmname 属性设置为 normalizedAlgorithmname 属性。

  6. publicKey 为一个新的 CryptoKey, 它表示所生成密钥对的公钥。

  7. publicKey[[type]] 内部槽设置为“public”。

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

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

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

  11. privateKey 为一个新的 CryptoKey, 它表示所生成密钥对的私钥。

  12. privateKey[[type]] 内部槽设置为“private”。

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

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

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

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

  17. resultpublicKey 属性设置为 publicKey

  18. resultprivateKey 属性设置为 privateKey

  19. 返回 result

8.4.4 导入密钥

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

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

    2. spki 为在 keyData 上运行 解析 subjectPublicKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-128s”:

      expectedOidid-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-128f”:

      expectedOidid-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-192s”:

      expectedOidid-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-192f”:

      expectedOidid-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-256s”:

      expectedOidid-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-256f”:

      expectedOidid-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-128s”:

      expectedOidid-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-128f”:

      expectedOidid-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-192s”:

      expectedOidid-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-192f”:

      expectedOidid-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-256s”:

      expectedOidid-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-256f”:

      expectedOidid-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31)。

      否则:

      抛出一个 NotSupportedError

    5. 如果 spkialgorithm AlgorithmIdentifier 字段的 algorithm 对象标识符字段 不等于 expectedOid, 则抛出一个 DataError

    6. 如果 spkialgorithm AlgorithmIdentifier 字段中存在 parameters 字段, 则抛出一个 DataError

    7. publicKey 为由 spkisubjectPublicKey 字段标识的 SLH-DSA 公钥。

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

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

    10. algorithm 为一个新的 KeyAlgorithm

    11. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

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

    2. privateKeyInfo 为在 keyData 上运行 解析 privateKeyInfo 算法所得的结果。

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

    4. 如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-128s”:

      expectedOidid-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-128f”:

      expectedOidid-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-192s”:

      expectedOidid-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-192f”:

      expectedOidid-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-256s”:

      expectedOidid-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHA2-256f”:

      expectedOidid-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-128s”:

      expectedOidid-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-128f”:

      expectedOidid-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-192s”:

      expectedOidid-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-192f”:

      expectedOidid-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-256s”:

      expectedOidid-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30)。

      如果 normalizedAlgorithmname 成员是 “SLH-DSA-SHAKE-256f”:

      expectedOidid-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31)。

      否则:

      抛出一个 NotSupportedError

    5. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithm 字段的 algorithm 对象标识符字段不等于 expectedOid, 则抛出一个 DataError

    6. 如果 privateKeyInfoprivateKeyAlgorithm PrivateKeyAlgorithmIdentifier 字段中 存在 parameters 字段, 则抛出一个 DataError

    7. slhDsaPrivateKey 为执行 解析 ASN.1 结构 算法所得的结果,其中将 privateKeyInfoprivateKey 字段用作 data, 将 OCTET STRING 用作 structure,并 将 exactData 设置为 true。

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

    9. key 为一个新的 CryptoKey, 它表示由 slhDsaPrivateKey 标识的 SLH-DSA 私钥。

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

    11. algorithm 为一个新的 KeyAlgorithm

    12. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

    如果 format 是“raw-public”:
    1. 如果 usages 包含不是 “verify”的条目, 则抛出一个 SyntaxError

    2. algorithm 为一个新的 KeyAlgorithm 对象。

    3. algorithmname 属性设置为 normalizedAlgorithmname 属性。

    4. 如果 keyData长度不是 [FIPS-205] 表 2 针对由 normalizedAlgorithmname 成员指示的参数集所规定的 pk length, 则抛出一个 DataError

    5. key 为一个新的 CryptoKey, 它表示 keyData 中提供的密钥数据。

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

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

    如果 format 是“raw-private”:
    1. 如果 usages 包含不是 “sign”的条目, 则抛出一个 SyntaxError

    2. 如果 keyData长度不是 [FIPS-205] 表 2 针对由 normalizedAlgorithmname 成员指示的参数集所规定的 pk length 的 2 倍, 则抛出一个 DataError

    3. key 为一个新的 CryptoKey, 它表示 keyData 中提供的密钥数据。

    4. key[[type]] 内部槽设置为“private”。

    5. algorithm 为一个新的 KeyAlgorithm

    6. algorithmname 属性设置为 normalizedAlgorithmname 属性。

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

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

      jwk 等于 keyData

      否则:

      抛出一个 DataError

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

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

    4. 如果 jwkalg 字段不等于 normalizedAlgorithmname 成员, 则抛出一个 DataError

    5. 如果 usages 非空,且 jwk 中存在 use 字段, 并且该字段不等于“sig”,则抛出一个 DataError

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

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

    8. 如果 jwk 中存在 priv 字段:
      1. 如果 jwkpriv 属性不包含表示 SLH-DSA 私钥的 有效 base64url 编码值, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpriv 属性解释为 base64url 编码私钥所标识的 SLH-DSA 私钥。

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

      4. 如果 jwkpub 属性不包含表示与 key 对应的 SLH-DSA 公钥的 base64url 编码公钥, 则抛出 一个 DataError

      否则:
      1. 如果 jwkpub 属性不包含表示 SLH-DSA 公钥的 有效 base64url 编码公钥, 则抛出 一个 DataError

      2. key 为一个新的 CryptoKey 对象,它表示通过将 jwkpub 属性解释为 base64url 编码公钥所标识的 SLH-DSA 公钥。

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

    9. algorithm 为一个新的 KeyAlgorithm 对象实例。

    10. algorithmname 属性设置为 normalizedAlgorithmname 成员。

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

    否则:

    抛出一个 NotSupportedError

  3. 返回 key

8.4.5 导出密钥

  1. key 为要导出的 CryptoKey

  2. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

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

        • 如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-128s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-128f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-192s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-192f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-256s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-256f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-128s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-128f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-192s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-192f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-256s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-256f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31) OID。

          否则:

          抛出 一个 NotSupportedError

      • subjectPublicKey 字段设置为 keyData

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

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

      • version 字段设置为 0

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

        • 如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-128s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-128f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-192s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-192f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-256s”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHA2-256f”:

          algorithm 对象标识符设置为 id-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-128s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-128f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-192s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-192f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-256s”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30) OID。

          如果 keyAlgorithmname 成员是 “SLH-DSA-SHAKE-256f”:

          algorithm 对象标识符设置为 id-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31) OID。

          否则:

          抛出 一个 NotSupportedError

      • privateKey 字段设置为对一个 OCTET STRING ASN.1 类型进行 DER 编码所得的结果, 该类型表示由 key[[handle]] 内部槽所表示的 SLH-DSA 私钥。

    4. result 为对 data 进行 DER 编码所得的结果。

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

    2. data 为一个字节序列, 其中包含由 key[[handle]] 内部槽所表示的 SLH-DSA 公钥。

    3. resultdata

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

    2. data 为一个字节序列, 其中包含由 key[[handle]] 内部槽所表示的 SLH-DSA 私钥。

    3. resultdata

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

    2. keyAlgorithmkey[[algorithm]] 内部槽。

    3. jwkkty 属性设置为 “AKP”。

    4. jwkalg 属性设置为 keyAlgorithmname 成员。

    5. jwkpub 属性 设置为与 key[[handle]] 内部槽对应的 base64url 编码公钥。

    6. 如果 key[[type]] 内部槽是“private”:
      jwkpriv 属性 设置为由 key[[handle]] 内部槽所表示的 base64url 编码私钥。
    7. jwkkey_ops 属性设置为 keyusages 属性。

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

    9. resultjwk

    否则:

    抛出一个 NotSupportedError

  4. 返回 result

9. AES-OCB

9.1 描述

本节不具规范性。

AES-OCB”算法标识符用于按照 [RFC7253] 中的描述, 使用 OCB 模式下的 AES 执行认证加密和解密。

9.2 注册

此算法的已识别算法名称 是“AES-OCB”。

操作 参数 结果
encrypt AeadParams 字节 序列
decrypt AeadParams 字节 序列
generateKey AesKeyGenParams CryptoKey
importKey CryptoKey
exportKey 对象
get key length AesDerivedKeyParams 整数

9.3 AeadParams 字典

WebIDLdictionary AeadParams : Algorithm {
  required BufferSource iv;
  BufferSource additionalData;
  [EnforceRange] octet tagLength;
};

iv 成员表示要使用的初始化向量。

additionalData 成员表示要包含的 附加认证数据。

tagLength 成员表示所需的 认证标签长度。

AeadParams 字典与 [webcrypto] 的 AesGcmParams 字典相同,在合并本提案时,后者可以由前者替代。

9.4 操作

9.4.1 加密

  1. 如果 normalizedAlgorithmiv 成员的长度大于 15 字节, 则抛出一个 OperationError

  2. 如果 normalizedAlgorithm 中不存在 tagLength 成员:
    tagLength 为 128。
    如果 normalizedAlgorithmtagLength 成员是 64、96 或 128 之一:
    tagLength 等于 normalizedAlgorithmtagLength 成员
    否则:
    抛出一个 OperationError
  3. 如果 normalizedAlgorithm 中存在 additionalData 成员, 则令 additionalData 为该成员;否则令其为空八位字节 字符串。

  4. C 为使用 AES 作为 分组密码,执行 [RFC7253] 第 4.2 节中描述的 OCB-ENCRYPT 函数所得的输出,其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 normalizedAlgorithmiv 成员作为 N 输入参数, 使用 additionalData 作为 A 输入参数, 使用 plaintext 作为 P 输入参数,并 使用 tagLength 作为 TAGLEN 全局参数。

  5. 返回 C

9.4.2 解密

  1. 如果 normalizedAlgorithmiv 成员的长度大于 15 字节, 则抛出一个 OperationError

  2. 如果 normalizedAlgorithm 中不存在 tagLength 成员:
    tagLength 为 128。
    如果 normalizedAlgorithmtagLength 成员是 64、96 或 128 之一:
    tagLength 等于 normalizedAlgorithmtagLength 成员
    否则:
    抛出一个 OperationError
  3. 如果 ciphertext 的长度小于 tagLength 比特, 则抛出一个 OperationError

  4. 如果 normalizedAlgorithm 中存在 additionalData 成员, 则令 additionalData 为该成员;否则令其为空八位字节 字符串。

  5. 使用 AES 作为分组密码,执行 [RFC7253] 第 4.3 节中描述的 OCB-DECRYPT 函数,其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 normalizedAlgorithmiv 成员作为 N 输入参数, 使用 additionalData 作为 A 输入参数, 使用 ciphertext 作为 C 输入参数,并 使用 tagLength 作为 TAGLEN 全局参数。

    如果算法结果是表示认证失败的 “INVALID”:
    抛出一个 OperationError
    否则:
    plaintext 为 OCB-DECRYPT 的输出 P
  6. 返回 plaintext

9.4.3 生成密钥

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

  2. 如果 normalizedAlgorithmlength 成员不等于 128、192 或 256 之一, 则抛出一个 OperationError

  3. 生成一个长度等于 normalizedAlgorithmlength 成员的 AES 密钥。

  4. 如果密钥生成步骤失败, 则抛出一个 OperationError

  5. key 为一个新的 CryptoKey 对象,表示所生成的 AES 密钥。

  6. key[[type]] 内部槽设置为“secret”。

  7. algorithm 为一个新的 AesKeyAlgorithm

  8. algorithmname 属性设置为“AES-OCB”。

  9. algorithmlength 属性设置为等于 normalizedAlgorithmlength 成员。

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

  11. key[[extractable]] 内部槽设置为 extractable

  12. key[[usages]] 内部槽设置为 usages

  13. 返回 key

9.4.4 导入密钥

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

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

  3. 如果 format 是“raw-secret”:
    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 比特:
      如果 jwk 中存在 alg 字段,并且该字段不是“A128OCB”, 则抛出一个 DataError
      如果 data 的长度为 192 比特:
      如果 jwk 中存在 alg 字段,并且该字段不是“A192OCB”, 则抛出一个 DataError
      如果 data 的长度为 256 比特:
      如果 jwk 中存在 alg 字段,并且该字段不是“A256OCB”, 则抛出一个 DataError
      否则:
      抛出一个 DataError
    6. 如果 usages 非空,且 jwk 中存在 use 字段,并且该字段不是“enc”, 则抛出一个 DataError

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

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

    否则:
    抛出一个 NotSupportedError
  4. key 为一个新的 CryptoKey 对象,表示值为 data 的 AES 密钥。

  5. key[[type]] 内部槽设置为“secret”。

  6. algorithm 为一个新的 AesKeyAlgorithm

  7. algorithmname 属性设置为“AES-OCB”。

  8. algorithmlength 属性设置为 data 的比特长度。

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

  10. 返回 key

9.4.5 导出密钥

  1. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

  2. 如果 format 是“raw-secret”:
    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 属性设置为 字符串“A128OCB”。
      如果 keylength 属性为 192:
      jwkalg 属性设置为 字符串“A192OCB”。
      如果 keylength 属性为 256:
      jwkalg 属性设置为 字符串“A256OCB”。
    5. jwkkey_ops 属性设置为等于 keyusages 属性。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    7. resultjwk

    否则:

    抛出一个 NotSupportedError

  3. 返回 result

9.4.6 获取密钥长度

  1. 如果 normalizedDerivedKeyAlgorithmlength 成员不是 128、192 或 256,则抛出一个 OperationError

  2. 返回 normalizedDerivedKeyAlgorithmlength 成员。

10. ChaCha20-Poly1305

10.1 描述

本节不具规范性。

ChaCha20-Poly1305”算法标识符用于按照 [RFC8439] 中的描述, 使用 AEAD_CHACHA20_POLY1305 执行认证加密和解密。

10.2 注册

此算法的已识别算法名称 是“ChaCha20-Poly1305”。

操作 参数 结果
encrypt AeadParams 字节 序列
decrypt AeadParams 字节 序列
generateKey CryptoKey
importKey CryptoKey
exportKey 对象
get key length 整数

10.3 操作

10.3.1 加密

  1. 如果 normalizedAlgorithmiv 成员的长度不是 12 字节, 则抛出一个 OperationError

  2. 如果 normalizedAlgorithm 中存在 tagLength 成员, 且该成员不是 128, 则抛出一个 OperationError

  3. 如果 normalizedAlgorithm 中存在 additionalData 成员, 则令 additionalData 为该成员;否则令其为空八位字节 字符串。

  4. ciphertext 为执行 [RFC8439] 第 2.8 节中描述的 AEAD_CHACHA20_POLY1305 加密算法 所得的输出,其中使用 key[[handle]] 内部槽所表示的密钥作为密钥输入参数, 使用 normalizedAlgorithmiv 成员作为 nonce 输入参数, 使用 plaintext 作为明文输入参数,并 使用 additionalData 作为附加认证数据(AAD)输入参数。

  5. 返回 ciphertext

10.3.2 解密

  1. 如果 normalizedAlgorithmiv 成员的长度不是 12 字节, 则抛出一个 OperationError

  2. 如果 normalizedAlgorithm 中存在 tagLength 成员, 且该成员不是 128, 则抛出一个 OperationError

  3. 如果 ciphertext 的长度小于 128 比特, 则抛出一个 OperationError

  4. 如果 normalizedAlgorithm 中存在 additionalData 成员, 则令 additionalData 为该成员;否则令其为空八位字节 字符串。

  5. 执行 [RFC8439] 第 2.8 节中描述的 AEAD_CHACHA20_POLY1305 解密算法,其中使用 key[[handle]] 内部槽所表示的密钥作为密钥输入参数, 使用 normalizedAlgorithmiv 成员作为 nonce 输入参数, 使用 ciphertext 作为密文输入参数,并 使用 additionalData 作为附加认证数据(AAD)输入参数。

    如果算法结果表示认证失败:
    抛出一个 OperationError
    否则:
    plaintext 为所得的明文。
  6. 返回 plaintext

10.3.3 生成密钥

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

  2. 生成一个 256 比特的密钥。

  3. 如果密钥生成步骤失败, 则抛出一个 OperationError

  4. key 为一个新的 CryptoKey 对象,表示所生成的 密钥。

  5. key[[type]] 内部槽设置为“secret”。

  6. algorithm 为一个新的 KeyAlgorithm

  7. algorithmname 属性设置为“ChaCha20-Poly1305”。

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

  9. key[[extractable]] 内部槽设置为 extractable

  10. key[[usages]] 内部槽设置为 usages

  11. 返回 key

10.3.4 导入密钥

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

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

  3. 如果 format 是“raw-secret”:
    1. datakeyData

    2. 如果 data 的比特长度不是 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. 如果 jwk 中存在 alg 字段,并且该字段不是“C20P”, 则抛出一个 DataError

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

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

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

    否则:
    抛出一个 NotSupportedError
  4. key 为一个新的 CryptoKey 对象,表示值为 data 的密钥。

  5. key[[type]] 内部槽设置为“secret”。

  6. algorithm 为一个新的 KeyAlgorithm

  7. algorithmname 属性设置为“ChaCha20-Poly1305”。

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

  9. 返回 key

10.3.5 导出密钥

  1. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

  2. 如果 format 是“raw-secret”:
    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. jwkalg 属性设置为 字符串“C20P”。

    5. jwkkey_ops 属性设置为等于 keyusages 属性。

    6. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    7. resultjwk

    否则:

    抛出一个 NotSupportedError

  3. 返回 result

10.3.6 获取密钥长度

  1. 返回 256。

11. SHA-3

11.1 描述

本节不具规范性。

本节描述了 [FIPS-202] 中规定的 SHA-3 哈希函数族。

11.2 注册

对应 SHA-3 算法的已识别算法 名称分别是 “SHA3-256”、 “SHA3-384”和 “SHA3-512”。

操作 参数 结果
digest 字节 序列

11.3 操作

11.3.1 摘要

  1. 如果 normalizedAlgorithmname 成员与 “SHA3-256”区分大小写地匹配:
    result 为执行 [FIPS-202] 第 6.1 节中定义的 SHA3-256 哈希函数所得的结果, 其中使用 message 作为输入消息 M
    如果 normalizedAlgorithmname 成员与 “SHA3-384”区分大小写地匹配:
    result 为执行 [FIPS-202] 第 6.1 节中定义的 SHA3-384 哈希函数所得的结果, 其中使用 message 作为输入消息 M
    如果 normalizedAlgorithmname 成员与 “SHA3-512”区分大小写地匹配:
    result 为执行 [FIPS-202] 第 6.1 节中定义的 SHA3-512 哈希函数所得的结果, 其中使用 message 作为输入消息 M
  2. 如果执行操作时发生错误,则抛出一个 OperationError

  3. 返回 result

12. cSHAKE

12.1 描述

本节不具规范性。

本节描述了 [NIST-SP800-185] 中规定的 cSHAKE128 和 cSHAKE256。

functionNamecustomization 参数均为空(或未提供)时,cSHAKE 在功能上等同于 [FIPS-202] 第 6.2 节中定义的 SHAKE。

12.2 注册

已识别算法 名称是 “cSHAKE128”和 “cSHAKE256”。

操作 参数 结果
digest CShakeParams 字节 序列

12.3 CShakeParams 字典

WebIDLdictionary CShakeParams : Algorithm {
  required [EnforceRange] unsigned long outputLength;
  BufferSource functionName;
  BufferSource customization;
};

outputLength 成员表示所请求的 输出比特长度。

functionName 成员表示函数 名称,NIST 使用该名称定义基于 cSHAKE 的函数。使用时,只应将其设置为 NIST 定义的值。

customization 成员表示 自定义字符串。应用程序选择此字符串以定义该函数的一个变体。

12.4 操作

12.4.1 摘要

  1. outputLengthnormalizedAlgorithmoutputLength 成员。

  2. 如果 normalizedAlgorithm 中存在 functionName 成员, 则令 functionName 为该成员;否则令其为空八位字节 字符串。

  3. 如果 normalizedAlgorithm 中存在 customization 成员, 则令 customization 为该成员;否则令其为空八位字节 字符串。

  4. 如果 normalizedAlgorithmname 成员与 “cSHAKE128”区分大小写地匹配:
    result 为执行 [NIST-SP800-185] 第 3 节中定义的 cSHAKE128 函数所得的结果, 其中使用 message 作为 X 输入参数, 使用 outputLength 作为 L 输入参数, 使用 functionName 作为 N 输入参数,并 使用 customization 作为 S 输入参数。
    如果 normalizedAlgorithmname 成员与 “cSHAKE256”区分大小写地匹配:
    result 为执行 [NIST-SP800-185] 第 3 节中定义的 cSHAKE256 函数所得的结果, 其中使用 message 作为 X 输入参数, 使用 outputLength 作为 L 输入参数, 使用 functionName 作为 N 输入参数,并 使用 customization 作为 S 输入参数。
  5. 如果执行操作时发生错误,则抛出一个 OperationError

  6. 返回一个包含 result 的字节序列

13. TurboSHAKE

13.1 描述

本节不具规范性。

本节描述了 [RFC9861] 中规定的 TurboSHAKE128 和 TurboSHAKE256。

TurboSHAKE 是一个可扩展输出函数(XOF)族,它基于 SHA-3 中所用 Keccak 置换的减少轮数版本,因此 在保持相同安全强度的同时,其速度大约是 SHAKE 函数的两倍。

为达到 128 比特碰撞安全性,TurboSHAKE128 的输出应至少为 256 比特。 为达到 256 比特碰撞安全性,TurboSHAKE256 的输出应至少为 512 比特。 这些输出长度也超过相应的原像和第二原像安全性 要求(后者只要求输出长度等于目标安全级别)。 当输出长度达到这些阈值时,TurboSHAKE128 达到 NIST 后量子 安全级别 2,TurboSHAKE256 达到级别 5。 参见 [RFC9861] 第 7 节。

13.2 注册

已识别算法 名称是 “TurboSHAKE128”和 “TurboSHAKE256”。

操作 参数 结果
digest TurboShakeParams 字节 序列

13.3 TurboShakeParams 字典

WebIDLdictionary TurboShakeParams : Algorithm {
  required [EnforceRange] unsigned long outputLength;
  [EnforceRange] octet domainSeparation;
};

outputLength 成员表示所请求的 输出比特长度。

domainSeparation 成员表示域 分离字节。如果未指定,则默认为 0x1F。有效值范围为 0x010x7F

同时使用 KangarooTwelve 和 TurboSHAKE 的协议应避免将 0x060x070x0B 用于域分离, 因为 KangarooTwelve 会在内部使用这些值。

13.4 操作

13.4.1 摘要

  1. outputLengthnormalizedAlgorithmoutputLength 成员。

  2. 如果 outputLength 为零或不是 8 的倍数, 则抛出一个 OperationError

  3. 如果 normalizedAlgorithm 中存在 domainSeparation 成员,则令 domainSeparation 为该成员; 否则令其为 0x1F

  4. 如果 domainSeparation 小于 0x01 或大于 0x7F, 则抛出一个 OperationError

  5. 如果 normalizedAlgorithmname 成员与 “TurboSHAKE128”区分大小写地匹配:
    result 为执行 [RFC9861] 第 2 节中定义的 TurboSHAKE128 函数所得的结果, 其中使用 message 作为 M 输入参数, 使用 domainSeparation 作为 D 输入参数,并 使用 outputLength 除以 8 所得的值作为 L 输入参数。
    如果 normalizedAlgorithmname 成员与 “TurboSHAKE256”区分大小写地匹配:
    result 为执行 [RFC9861] 第 2 节中定义的 TurboSHAKE256 函数所得的结果, 其中使用 message 作为 M 输入参数, 使用 domainSeparation 作为 D 输入参数,并 使用 outputLength 除以 8 所得的值作为 L 输入参数。
  6. 如果执行操作时发生错误,则抛出一个 OperationError

  7. 返回 result

14. KangarooTwelve

14.1 描述

本节不具规范性。

本节描述了 [RFC9861] 中规定的 KT128 和 KT256。

KangarooTwelve 是一个可扩展输出函数(XOF)族,它在 TurboSHAKE 之上应用树哈希,从而能够并行处理输入数据。 KT128 在内部使用 TurboSHAKE128,而 KT256 使用 TurboSHAKE256。

为达到 128 比特碰撞安全性,KT128 的输出应至少为 256 比特。 为达到 256 比特碰撞安全性,KT256 的输出应至少为 512 比特。 这些输出长度也超过相应的原像和第二原像安全性 要求(后者只要求输出长度等于目标安全级别)。 当输出长度达到这些阈值时,KT128 达到 NIST 后量子 安全级别 2,KT256 达到级别 5。 参见 [RFC9861] 第 7 节。

14.2 注册

已识别算法 名称是 “KT128”和 “KT256”。

操作 参数 结果
digest KangarooTwelveParams 字节 序列

14.3 KangarooTwelveParams 字典

WebIDLdictionary KangarooTwelveParams : Algorithm {
  required [EnforceRange] unsigned long outputLength;
  BufferSource customization;
};

outputLength 成员表示所请求的 输出比特长度。

customization 成员表示 自定义字符串。应用程序选择此字符串以定义该函数的一个变体。如果未 指定,则默认为空字符串。

14.4 操作

14.4.1 摘要

  1. outputLengthnormalizedAlgorithmoutputLength 成员。

  2. 如果 outputLength 为零或不是 8 的倍数, 则抛出一个 OperationError

  3. 如果 normalizedAlgorithm 中存在 customization 成员,则令 customization 为该成员;否则令其为空八位字节 字符串。

  4. 如果 normalizedAlgorithmname 成员与 “KT128”区分大小写地匹配:
    result 为执行 [RFC9861] 第 3 节中定义的 KT128 函数所得的结果, 其中使用 message 作为 M 输入参数, 使用 customization 作为 C 输入参数,并 使用 outputLength 除以 8 所得的值作为 L 输入参数。
    如果 normalizedAlgorithmname 成员与 “KT256”区分大小写地匹配:
    result 为执行 [RFC9861] 第 3 节中定义的 KT256 函数所得的结果, 其中使用 message 作为 M 输入参数, 使用 customization 作为 C 输入参数,并 使用 outputLength 除以 8 所得的值作为 L 输入参数。
  5. 如果执行操作时发生错误,则抛出一个 OperationError

  6. 返回 result

15. KMAC

15.1 描述

本节不具规范性。

本节描述了 [NIST-SP800-185] 中规定的 KMAC128 和 KMAC256。

15.2 注册

已识别算法 名称是 “KMAC128”和 “KMAC256”。

操作 参数 结果
sign KmacParams 字节 序列
verify KmacParams 布尔值
generateKey KmacKeyGenParams CryptoKey
importKey KmacImportParams CryptoKey
exportKey 对象
get key length KmacImportParams 整数

15.3 KmacKeyGenParams 字典

WebIDLdictionary KmacKeyGenParams : Algorithm {
  [EnforceRange] unsigned long length;
};

length 成员表示要生成的密钥的 长度(以比特为单位)。如果未指定,则使用推荐长度,KMAC128 为 128, KMAC256 为 256。

15.4 KmacImportParams 字典

WebIDLdictionary KmacImportParams : Algorithm {
  [EnforceRange] unsigned long length;
};

length 成员表示密钥的长度 (以比特为单位)。

15.5 KmacKeyAlgorithm 字典

WebIDLdictionary KmacKeyAlgorithm : KeyAlgorithm {
  required unsigned long length;
};

length 成员表示密钥的长度 (以比特为单位)。

15.6 KmacParams 字典

WebIDLdictionary KmacParams : Algorithm {
  required [EnforceRange] unsigned long outputLength;
  BufferSource customization;
};

outputLength 成员表示所请求的 输出比特长度。

customization 成员表示 自定义字符串。应用程序选择此字符串以定义该函数的一个变体。

15.7 操作

15.7.1 签名

  1. 如果 normalizedAlgorithm 中存在 customization 成员, 则令 customization 为该成员;否则令其为空八位字节 字符串。

  2. 如果 normalizedAlgorithmname 成员与 “KMAC128”区分大小写地匹配:
    mac 为执行 [NIST-SP800-185] 第 4 节中定义的 KMAC128 函数所得的结果, 其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 message 作为 X 输入参数, 使用 normalizedAlgorithmoutputLength 成员作为 L 输入参数,并 使用 customization 作为 S 输入参数。
    如果 normalizedAlgorithmname 成员与 “KMAC256”区分大小写地匹配:
    mac 为执行 [NIST-SP800-185] 第 4 节中定义的 KMAC256 函数所得的结果, 其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 message 作为 X 输入参数, 使用 normalizedAlgorithmoutputLength 成员作为 L 输入参数,并 使用 customization 作为 S 输入参数。
  3. 返回一个包含 mac 的字节序列

15.7.2 验证

  1. 如果 normalizedAlgorithm 中存在 customization 成员, 则令 customization 为该成员;否则令其为空八位字节 字符串。

  2. 如果 normalizedAlgorithmname 成员与 “KMAC128”区分大小写地匹配:
    mac 为执行 [NIST-SP800-185] 第 4 节中定义的 KMAC128 函数所得的结果, 其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 message 作为 X 输入参数, 使用 normalizedAlgorithmoutputLength 成员作为 L 输入参数,并 使用 customization 作为 S 输入参数。
    如果 normalizedAlgorithmname 成员与 “KMAC256”区分大小写地匹配:
    mac 为执行 [NIST-SP800-185] 第 4 节中定义的 KMAC256 函数所得的结果, 其中使用 key[[handle]] 内部槽所表示的密钥作为 K 输入参数, 使用 message 作为 X 输入参数, 使用 normalizedAlgorithmoutputLength 成员作为 L 输入参数,并 使用 customization 作为 S 输入参数。
  3. computedMac 为一个包含 mac 的字节序列

  4. 如果 computedMac 等于 signature,则返回 true;否则 返回 false。 此比较必须以常量时间执行。

15.7.3 生成密钥

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

  2. 如果 normalizedAlgorithm 中存在 length 成员:
    length 等于 normalizedAlgorithmlength 成员。
    否则,如果 normalizedAlgorithmname 成员与 “KMAC128”区分大小写地匹配:
    length 为 128。
    否则,如果 normalizedAlgorithmname 成员与 “KMAC256”区分大小写地匹配:
    length 为 256。
  3. 生成一个长度为 length 比特的密钥。

  4. 如果密钥生成步骤失败, 则抛出一个 OperationError

  5. key 为一个新的 CryptoKey 对象,表示所生成的 密钥。

  6. key[[type]] 内部槽设置为“secret”。

  7. algorithm 为一个新的 KmacKeyAlgorithm

  8. algorithmname 属性设置为 normalizedAlgorithmname 成员。

  9. algorithmlength 属性设置为 length

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

  11. key[[extractable]] 内部槽设置为 extractable

  12. key[[usages]] 内部槽设置为 usages

  13. 返回 key

15.7.4 导入密钥

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

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

  3. 如果 format 是“raw-secret”:
    1. datakeyData

    如果 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. 如果 normalizedAlgorithmname 成员与 “KMAC128”区分大小写地匹配:
      如果 jwk 中存在 alg 字段,并且该字段不是“K128”, 则抛出一个 DataError
      如果 normalizedAlgorithmname 成员与 “KMAC256”区分大小写地匹配:
      如果 jwk 中存在 alg 字段,并且该字段不是“K256”, 则抛出一个 DataError
    6. 如果 usages 非空,且 jwk 中存在 use 字段,并且该字段不是“sig”, 则抛出一个 DataError

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

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

    否则:
    抛出一个 NotSupportedError
  4. lengthdata 的比特长度。

  5. 如果 normalizedAlgorithm 中存在 length 成员:
    如果 normalizedAlgorithmlength 成员 大于 length
    抛出一个 DataError
    如果 normalizedAlgorithmlength 成员 小于或等于 length 减 8:
    抛出一个 DataError
    否则:
    length 设置为等于 normalizedAlgorithmlength 成员。
  6. key 为一个新的 CryptoKey 对象,表示由 data 的前 length 比特组成的 KMAC 密钥。

  7. key[[type]] 内部槽设置为“secret”。

  8. algorithm 为一个新的 KmacKeyAlgorithm

  9. algorithmname 属性设置为 normalizedAlgorithmname 成员。

  10. algorithmlength 属性设置为 length

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

  12. 返回 key

15.7.5 导出密钥

  1. 如果无法访问 key[[handle]] 内部槽所表示的底层密码密钥材料, 则抛出一个 OperationError

  2. bits 为由 key[[handle]] 内部槽所表示的密钥的原始比特。

  3. data 为一个包含 bits 的字节序列

  4. 如果 format 是“raw-secret”:
    1. resultdata

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

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

    3. jwkk 属性设置为一个包含 data 的字符串,并按照 JSON Web Algorithms [JWA] 第 6.4 节进行编码。

    4. keyAlgorithmkey[[algorithm]] 内部槽。

    5. 如果 keyAlgorithmname 成员是“KMAC128”:
      jwkalg 属性设置为 字符串“K128”。
      如果 keyAlgorithmname 成员是“KMAC256”:
      jwkalg 属性设置为 字符串“K256”。
    6. jwkkey_ops 属性设置为等于 keyusages 属性。

    7. jwkext 属性设置为等于 key[[extractable]] 内部槽。

    8. resultjwk

    否则:

    抛出一个 NotSupportedError

  5. 返回 result

15.7.6 获取密钥长度

  1. 如果 normalizedAlgorithm 中存在 length 成员:
    length 等于 normalizedAlgorithmlength 成员。
    否则,如果 normalizedAlgorithmname 成员与 “KMAC128”区分大小写地匹配:
    length 为 128。
    否则,如果 normalizedAlgorithmname 成员与 “KMAC256”区分大小写地匹配:
    length 为 256。
  2. 返回 length

16. Argon2

16.1 描述

本节不具规范性。

本节描述了用于密码哈希和密钥派生的 Argon2 函数, 如 [RFC9106] 中所定义。

16.2 注册

相应 Argon2 类型的已识别算法 名称分别是 “Argon2d”、 “Argon2i”和 “Argon2id”。

操作 参数 结果
deriveBits Argon2Params 字节 序列
importKey CryptoKey
get key length null

16.3 Argon2Params 字典

WebIDLdictionary Argon2Params : Algorithm {
  required BufferSource nonce;
  required [EnforceRange] unsigned long parallelism;
  required [EnforceRange] unsigned long memory;
  required [EnforceRange] unsigned long passes;
  [EnforceRange] octet version;
  BufferSource secretValue;
  BufferSource associatedData;
};

nonce 成员表示 nonce,在密码哈希应用程序中 它用作盐值。

parallelism 成员表示 并行度。

memory 成员表示以 KiB 为单位的内存大小。它必须至少是并行度的 8 倍。

passes 成员表示 轮数。

version 成员表示版本号。默认版本和 当前唯一已定义的版本是 19(0x13)。

secretValue 成员表示可选的 秘密值。

associatedData 成员表示可选的 关联数据。

有关参数的推荐值,请参见 [RFC9106] 第 4 节。

16.4 操作

16.4.1 派生比特

  1. 如果 length 为 null、小于 32(4*8)或不是 8 的倍数, 则抛出一个 OperationError

  2. 如果 normalizedAlgorithm 中存在 version 成员, 且该成员不是 19(0x13), 则抛出一个 OperationError

  3. 如果 normalizedAlgorithmparallelism 成员为零, 或大于 16777215(2^24-1), 则抛出一个 OperationError

  4. 如果 normalizedAlgorithmmemory 成员小于 normalizedAlgorithmparallelism 成员的 8 倍, 则抛出一个 OperationError

  5. 如果 normalizedAlgorithmpasses 成员为零, 则抛出一个 OperationError

  6. 如果 normalizedAlgorithmname 成员与 “Argon2d”区分大小写地匹配:
    type 为 0。
    如果 normalizedAlgorithmname 成员与 “Argon2i”区分大小写地匹配:
    type 为 1。
    如果 normalizedAlgorithmname 成员与 “Argon2id”区分大小写地匹配:
    type 为 2。
  7. 如果 normalizedAlgorithm 中存在 secretValue 成员, 则令 secretValue 为该成员。

  8. 如果 normalizedAlgorithm 中存在 associatedData 成员, 则令 associatedData 为该成员。

  9. result 为执行 [RFC9106] 第 3 节中定义的 Argon2 函数所得的结果,其中使用 key[[handle]] 内部槽所表示的密码 作为消息 P, 使用 normalizedAlgorithmnonce 属性作为 nonce S, 使用 normalizedAlgorithmparallelism 属性的值 作为并行度 p, 使用 normalizedAlgorithmmemory 属性的值 作为内存大小 m, 使用 normalizedAlgorithmpasses 属性的值 作为轮数 t, 使用 0x13 作为版本号 v, 使用 secretValue(如果存在)作为秘密值 K, 使用 associatedData(如果存在)作为关联数据 X, 使用 type 作为类型 y,并 使用 length 除以 8 所得的值作为标签长度 T

  10. 如果密钥派生操作失败, 则抛出一个 OperationError

  11. 返回 result

16.4.2 导入密钥

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

  2. 如果 format 不是“raw-secret”,则抛出一个 NotSupportedError

  3. 如果 usages 包含不是 “deriveKey”或“deriveBits”的值,则 抛出一个 SyntaxError

  4. 如果 extractable 不是 false, 则抛出一个 SyntaxError

  5. key 为一个新的 CryptoKey, 它表示 keyData

  6. key[[type]] 内部槽设置为“secret”。

  7. algorithm 为一个新的 KeyAlgorithm 对象。

  8. algorithmname 属性设置为 normalizedAlgorithmname 成员。

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

  10. 返回 key

16.4.3 获取密钥长度

  1. 返回 null。

17. IANA 注意事项

17.1 JSON Web 签名和加密算法注册

本节在 IANA JSON Web 签名和加密算法注册表中注册以下算法标识符, 以供 JSON Web Key 使用。

17.2 JSON Web Key 操作

本节在 IANA JSON Web Key 操作注册表中注册以下密钥操作, 以供 JSON Web Key 使用。

18. 采用指南

本节不具规范性。

本规范定义了许多算法和操作。为了向 实现者提供指导,并加速 Web 平台的后量子迁移, 本节建议应优先实现哪些算法和 操作。

SubtleCrypto.supports 方法通过支持特性检测、优雅 回退和渐进增强,简化了本规范中其他所有算法和 操作的快速采用。

SubtleCrypto.getPublicKey 方法对于实际使用本规范和 [webcrypto] 中定义的非对称算法非常重要。它允许应用程序只存储私钥而不存储 对应的公钥,也无需验证私钥和 公钥确实对应,从而简化了密钥管理。此外,它允许库 作者接受不可提取的私钥作为协议的输入, 这些协议会将公钥值承诺到其输出中。

就算法而言,以下算法被认为是后量子迁移以及 在 Web 上启用现代密码协议的最高 优先级,按优先级顺序排列:

  1. ML-KEM 是 NIST 标准化的主要后量子密钥 封装机制 [FIPS-203]。 与传统密钥协商结合使用时,它能够实现混合 后量子/传统(PQ/T)密钥建立,如 [draft-ietf-hpke-hpke] 等协议及其 PQ 和 PQ/T 算法 [draft-ietf-hpke-pq] 中所采用的方式。
  2. ML-DSA 是 NIST 标准化的主要后量子数字 签名算法 [FIPS-204]。
  3. ChaCha20-Poly1305 是一种广泛 部署的 AEAD 密码 [RFC8439],用于许多协议 (TLS、SSH、WireGuard、HPKE)。
  4. SHA-3cSHAKE (具体为 SHA3-256 和 cSHAKE256)用于许多后量子 构造,包括 ML-KEM 密钥派生和混合 KEM 组合器。值得注意的是,在不提供任何自定义 参数的情况下调用 cSHAKE256,会产生与 SHAKE256 相同的输出,因此一个 实现即可同时满足自定义(cSHAKE256)和 非自定义(SHAKE256)用例。 但是,如果没有 cSHAKE 实现, SHAKE 实现仍可能有用,但必须确保在 customization 参数存在且 非空时抛出 NotSupportedError(并使 SubtleCrypto.supports 返回 false)。
  5. Argon2 是一种内存困难的基于密码的 密钥派生函数 [RFC9106], 能够增强对高度并行化环境 (如 GPU 和 FPGA)中暴力破解攻击的抵抗能力。

SLH-DSA 是 NIST 标准化的一种无状态、基于哈希的数字 签名算法 [FIPS-204]。 目前它的采用程度 低于 ML-DSA,但如果需要 ML-DSA 的替代方案, 实现它可能会变得有用。

除此之外,AES-OCBTurboSHAKEKangarooTwelveKMAC 都是有价值的补充,但对于 后量子迁移而言并不那么紧迫。

19. 使用示例

此示例在 Argon2 可用时使用 Argon2 从密码派生密钥,否则使用 PBKDF2; 然后在 AES-OCB 可用时使用 AES-OCB 通过该密钥加密和解密一些文本,否则使用 AES-GCM。

示例 1:使用从密码派生的密钥加密一些数据
const password = 'correct horse battery staple';
const derivationAlg =
  SubtleCrypto.supports?.('importKey', 'Argon2id') ?
    'Argon2id' :
    'PBKDF2';
const encryptionAlg =
  SubtleCrypto.supports?.('importKey', 'AES-OCB') ?
    'AES-OCB' :
    'AES-GCM';
const passwordKey = await crypto.subtle.importKey(
  derivationAlg === 'Argon2id' ? 'raw-secret' : 'raw',
  new TextEncoder().encode(password),
  derivationAlg,
  /* 可提取: */ false,
  ['deriveKey']
);
const nonce = crypto.getRandomValues(new Uint8Array(16));
const derivationParams =
  derivationAlg === 'Argon2id' ?
    {
      nonce,
      parallelism: 4,
      memory: 2 ** 21,
      passes: 1
    } :
    {
      salt: nonce,
      iterations: 100_000,
      hash: 'SHA-256'
    };
const key = await crypto.subtle.deriveKey(
  {
    name: derivationAlg,
    ...derivationParams
  },
  passwordKey,
  {
    name: encryptionAlg,
    length: 256
  },
  /* 可提取: */ false,
  ['encrypt', 'decrypt']
);
const plaintext = 'Hello, world!';
const iv = crypto.getRandomValues(new Uint8Array(16));
const encrypted = await crypto.subtle.encrypt(
  { name: encryptionAlg, iv },
  key,
  new TextEncoder().encode(plaintext)
);
// 存储派生和加密算法及其参数
// 以及密文(例如存储在 IndexedDB 或数据库中),
// 并在以后检索它们。然后,使用原始参数和密码
// 派生密钥。此处我们立即使用同一个密钥对象
// 再次解密。
const decrypted = new TextDecoder().decode(await crypto.subtle.decrypt(
  { name: encryptionAlg, iv },
  key,
  encrypted
));

A. JSON Web Key / JSON Web Algorithm 之间的映射

本节不具规范性。

有关导入和导出 JWK 的规范性要求, 请参阅特定于算法的章节。

A.1 算法映射

JSON Web Key AlgorithmIdentifier
{ kty: "oct",
alg: "A128OCB" }
{ name: "AES-OCB",
length: 128 }
{ kty: "oct",
alg: "A192OCB" }
{ name: "AES-OCB",
length: 192 }
{ kty: "oct",
alg: "A256OCB" }
{ name: "AES-OCB",
length: 256 }
{ kty: "oct",
alg: "C20P" }
{ name: "ChaCha20-Poly1305" }
{ kty: "oct",
alg: "K128" }
{ name: "KMAC128" }
{ kty: "oct",
alg: "K256" }
{ name: "KMAC256" }

B. 算法与 PKCS#8 PrivateKeyInfo 之间的映射

本节不具规范性。

有关导入和导出 PKCS#8 PrivateKeyInfo 的 规范性要求,请参阅特定于算法的章节。

privateKeyAlgorithm privateKey 格式 AlgorithmIdentifier 参考文献
id-ml-dsa-44 (2.16.840.1.101.3.4.3.17) ML-DSA-44-PrivateKey "ML-DSA-44" [CSOR],[RFC9881]
id-ml-dsa-65 (2.16.840.1.101.3.4.3.18) ML-DSA-65-PrivateKey "ML-DSA-65" [CSOR],[RFC9881]
id-ml-dsa-87 (2.16.840.1.101.3.4.3.19) ML-DSA-87-PrivateKey "ML-DSA-87" [CSOR],[RFC9881]
id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1) ML-KEM-512-PrivateKey "ML-KEM-512" [CSOR],[RFC9935]
id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2) ML-KEM-768-PrivateKey "ML-KEM-768" [CSOR],[RFC9935]
id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3) ML-KEM-1024-PrivateKey "ML-KEM-1024" [CSOR],[RFC9935]
id-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20) OCTET STRING "SLH-DSA-SHA2-128s" [CSOR],[RFC9814]
id-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21) OCTET STRING "SLH-DSA-SHA2-128f" [CSOR],[RFC9814]
id-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22) OCTET STRING "SLH-DSA-SHA2-192s" [CSOR],[RFC9814]
id-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23) OCTET STRING "SLH-DSA-SHA2-192f" [CSOR],[RFC9814]
id-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24) OCTET STRING "SLH-DSA-SHA2-256s" [CSOR],[RFC9814]
id-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25) OCTET STRING "SLH-DSA-SHA2-256f" [CSOR],[RFC9814]
id-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26) OCTET STRING "SLH-DSA-SHAKE-128s" [CSOR],[RFC9814]
id-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27) OCTET STRING "SLH-DSA-SHAKE-128f" [CSOR],[RFC9814]
id-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28) OCTET STRING "SLH-DSA-SHAKE-192s" [CSOR],[RFC9814]
id-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29) OCTET STRING "SLH-DSA-SHAKE-192f" [CSOR],[RFC9814]
id-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30) OCTET STRING "SLH-DSA-SHAKE-256s" [CSOR],[RFC9814]
id-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31) OCTET STRING "SLH-DSA-SHAKE-256f" [CSOR],[RFC9814]

C. 算法与 SubjectPublicKeyInfo 之间的映射

本节不具规范性。

有关导入和导出 SPKI 的 规范性要求,请参阅特定于算法的章节。

算法 OID subjectPublicKey ASN.1 结构 AlgorithmIdentifier 参考文献
id-ml-dsa-44 (2.16.840.1.101.3.4.3.17) BIT STRING "ML-DSA-44" [CSOR],[RFC9881]
id-ml-dsa-65 (2.16.840.1.101.3.4.3.18) BIT STRING "ML-DSA-65" [CSOR],[RFC9881]
id-ml-dsa-87 (2.16.840.1.101.3.4.3.19) BIT STRING "ML-DSA-87" [CSOR],[RFC9881]
id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1) BIT STRING "ML-KEM-512" [CSOR],[RFC9935]
id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2) BIT STRING "ML-KEM-768" [CSOR],[RFC9935]
id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3) BIT STRING "ML-KEM-1024" [CSOR],[RFC9935]
id-slh-dsa-sha2-128s (2.16.840.1.101.3.4.3.20) BIT STRING "SLH-DSA-SHA2-128s" [CSOR],[RFC9814]
id-slh-dsa-sha2-128f (2.16.840.1.101.3.4.3.21) BIT STRING "SLH-DSA-SHA2-128f" [CSOR],[RFC9814]
id-slh-dsa-sha2-192s (2.16.840.1.101.3.4.3.22) BIT STRING "SLH-DSA-SHA2-192s" [CSOR],[RFC9814]
id-slh-dsa-sha2-192f (2.16.840.1.101.3.4.3.23) BIT STRING "SLH-DSA-SHA2-192f" [CSOR],[RFC9814]
id-slh-dsa-sha2-256s (2.16.840.1.101.3.4.3.24) BIT STRING "SLH-DSA-SHA2-256s" [CSOR],[RFC9814]
id-slh-dsa-sha2-256f (2.16.840.1.101.3.4.3.25) BIT STRING "SLH-DSA-SHA2-256f" [CSOR],[RFC9814]
id-slh-dsa-shake-128s (2.16.840.1.101.3.4.3.26) BIT STRING "SLH-DSA-SHAKE-128s" [CSOR],[RFC9814]
id-slh-dsa-shake-128f (2.16.840.1.101.3.4.3.27) BIT STRING "SLH-DSA-SHAKE-128f" [CSOR],[RFC9814]
id-slh-dsa-shake-192s (2.16.840.1.101.3.4.3.28) BIT STRING "SLH-DSA-SHAKE-192s" [CSOR],[RFC9814]
id-slh-dsa-shake-192f (2.16.840.1.101.3.4.3.29) BIT STRING "SLH-DSA-SHAKE-192f" [CSOR],[RFC9814]
id-slh-dsa-shake-256s (2.16.840.1.101.3.4.3.30) BIT STRING "SLH-DSA-SHAKE-256s" [CSOR],[RFC9814]
id-slh-dsa-shake-256f (2.16.840.1.101.3.4.3.31) BIT STRING "SLH-DSA-SHAKE-256f" [CSOR],[RFC9814]

D. 一致性

除标记为不具规范性的章节外,本规范中的所有编写指南、图表、示例和注释也都不具规范性。本规范中的其他所有内容均具规范性。

本文档中的关键词 必须 仅当像此处所示那样全部使用 大写字母时,才应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释。

E. 参考文献

E.1 规范性参考文献

[draft-ietf-jose-pqc-kem-05]
用于 JOSE 和 COSE 的后量子密钥 封装机制(PQ KEM). IETF. 2025年12月. URL: https://www.ietf.org/archive/id/draft-ietf-jose-pqc-kem-05.html
[FIPS-202]
SHA-3 标准: 基于置换的哈希函数和可扩展输出函数. NIST. 2015年8月. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
[FIPS-203]
基于模格的 密钥封装机制标准. NIST. 2024年8月. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf
[FIPS-204]
基于模格的 数字签名标准. NIST. 2024年8月. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf
[FIPS-205]
无状态的基于哈希的 数字签名标准. NIST. 2024年8月. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf
[html]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行 标准. URL: https://html.spec.whatwg.org/multipage/
[infra]
基础设施标准. Anne van Kesteren; Domenic Denicola. WHATWG. 现行标准. URL: https://infra.spec.whatwg.org/
[JWA]
JSON Web 算法(JWA). M. Jones. IETF. 2015年5月. 提议标准. URL: https://www.rfc-editor.org/info/rfc7518/
[JWK]
JSON Web Key(JWK). M. Jones. IETF. 2015年5月. 提议标准. URL: https://www.rfc-editor.org/info/rfc7517/
[NIST-SP800-185]
NIST 特别出版物 800-185:SHA-3 派生函数:cSHAKE、KMAC、TupleHash 和 ParallelHash. NIST. 2016年12月. URL: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf
[RFC2119]
用于 RFC 中指示 要求级别的关键词. S. Bradner. IETF. 1997年3月. 当前最佳实践. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC5208]
公钥密码学标准(PKCS) #8:私钥信息语法规范 1.2 版. B. Kaliski. IETF. 2008年5月. 资料性. URL: https://www.rfc-editor.org/info/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/info/rfc5280/
[RFC7253]
OCB 认证加密 算法. T. Krovetz; P. Rogaway. IETF. 2014年5月. 资料性. URL: https://www.rfc-editor.org/info/rfc7253/
[RFC8174]
RFC 2119 关键词中大写与小写的歧义. B. Leiba. IETF. 2017年5月. 当前最佳实践. URL: https://www.rfc-editor.org/info/rfc8174/
[RFC8439]
用于 IETF 协议的 ChaCha20 和 Poly1305. Y. Nir; A. Langley. IETF. 2018年6月. 资料性. URL: https://www.rfc-editor.org/info/rfc8439/
[RFC9106]
用于密码 哈希和工作量证明应用程序的 Argon2 内存困难函数. A. Biryukov; D. Dinu; D. Khovratovich; S. Josefsson. IETF. 2021年9月. 资料性. URL: https://www.rfc-editor.org/info/rfc9106/
[RFC9861]
KangarooTwelve 和 TurboSHAKE. IETF. 2025年10月. URL: https://www.rfc-editor.org/rfc/rfc9861.html
[RFC9964]
用于 JSON 对象签名与 加密(JOSE)和 CBOR 对象签名与加密(COSE)的 ML-DSA. M. Prorock; O. Steele. IETF. 2026年5月. 提议标准. URL: https://www.rfc-editor.org/info/rfc9964/
[webcrypto]
Web 加密第 2 级. Daniel Huigens. W3C. 2025年4月22日. 首个公开工作草案. URL: https://www.w3.org/TR/webcrypto-2/
[WebIDL]
Web IDL 标准. Edgar Chen; Timothy Gu. WHATWG. 现行标准. URL: https://webidl.spec.whatwg.org/

E.2 资料性参考文献

[CSOR]
计算机 安全对象注册表. NIST. URL: https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
[draft-ietf-hpke-hpke]
混合公钥 加密. IETF. URL: https://datatracker.ietf.org/doc/draft-ietf-hpke-hpke/
[draft-ietf-hpke-pq]
用于 HPKE 的后量子混合密钥 封装机制. IETF. URL: https://datatracker.ietf.org/doc/draft-ietf-hpke-pq/
[RFC9814]
在 密码消息语法(CMS)中使用 SLH-DSA 签名算法. R. Housley; S. Fluhrer; P. Kampanakis; B. Westerbaan. IETF. 2025年7月. 提议标准. URL: https://www.rfc-editor.org/info/rfc9814/
[RFC9881]
互联网 X.509 公钥基础设施—— 基于模格的数字签名算法 (ML-DSA)的算法标识符. J. Massimo; P. Kampanakis; S. Turner; B. E. Westerbaan. IETF. 2025年10月. 提议标准. URL: https://www.rfc-editor.org/info/rfc9881/
[RFC9935]
互联网 X.509 公钥基础设施—— 基于模格的密钥封装机制 (ML-KEM)的算法标识符. S. Turner; P. Kampanakis; J. Massimo; B. E. Westerbaan. IETF. 2026年3月. 提议标准. URL: https://www.rfc-editor.org/info/rfc9935/
[webcrypto-secure-curves]
Web 加密 API 中的安全曲线. W3C. 社区组报告草案. URL: https://wicg.github.io/webcrypto-secure-curves/