--- a/spec/Overview-CR.html Thu Nov 06 14:53:14 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17996 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>Web Cryptography API</title>
-
- <link rel="stylesheet" href="webcrypto.css" type="text/css" />
- <script src="section-links.js" type="application/ecmascript"></script>
- <script src="dfn.js" type="application/ecmascript"></script>
- <!--[if IE]>
- <style type='text/css'>
- .ignore {
- -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
- filter: alpha(opacity=50);
- }
- </style>
- <![endif]-->
-
-
- <link rel="stylesheet" href="//www.w3.org/StyleSheets/TR/W3C-CR" type="text/css" /></head>
-
- <body>
- <div class="head"><div><a href="http://www.w3.org/"><img src="//www.w3.org/Icons/w3c_home" width="72" height="48" alt="W3C" /></a></div><h1>Web Cryptography API</h1><h2>W3C Candidate Recommendation <em>NaN @@ rypt</em></h2><dl><dt>This Version:</dt><dd><a href="http://www.w3.org/TR/WebCryptoAPI/">http://www.w3.org/TR/WebCryptoAPI/</a></dd><dt>Latest Published Version:</dt><dd><a href="http://www.w3.org/TR/WebCryptoAPI/">http://www.w3.org/TR/WebCryptoAPI/</a></dd><dt>Latest Editor’s Draft:</dt><dd><a href="http://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html">http://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html</a></dd><dt>Previous Version(s):</dt><dd><a href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/0fe9b34c13fb/spec/Overview.html">https://dvcs.w3.org/hg/webcrypto-api/raw-file/0fe9b34c13fb/spec/Overview.html</a></dd><dt>Editors:</dt><dd><a href="http://www.google.com/">Ryan Sleevi</a>, Google, Inc. <sleevi@google.com></dd><dd><a href="http://www.netflix.com/">Mark Watson</a>, Netflix <watsonm@netflix.com></dd><dt>Participate:</dt><dd><p>Send feedback to <a href="mailto:public-webcrypto@w3.org?subject=%5BWebCryptoAPI%5D">public-webcrypto@w3.org</a> (<a href="http://lists.w3.org/Archives/Public/public-webcrypto/">archives</a>), or <a href="https://www.w3.org/Bugs/Public/enter_bug.cgi?product=Web%20Cryptography&component=Web%20Cryptography%20API%20Document">file a bug</a>
- (see <a href="https://www.w3.org/Bugs/Public/buglist.cgi?product=Web%20Cryptography&component=Web%20Cryptography%20API%20Document&resolution=---">existing bugs</a>).</p></dd></dl><p class="copyright"><a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © rypt <a href="http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="http://www.ercim.org/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply.</p></div><hr />
-
- <div class="section">
- <h2>Abstract</h2>
- <p>
- This specification describes a JavaScript API for performing basic
- cryptographic operations in web applications, such as hashing,
- signature generation and verification, and encryption and decryption.
- Additionally, it describes an API for applications to generate and/or
- manage the keying material necessary to perform these operations.
- Uses for this API range from user or service authentication, document
- or code signing, and the confidentiality and integrity of
- communications.
- </p>
-
-
- </div>
-
- <div class="section">
- <h2>Status of this Document</h2>
- <p><em>
- This section describes the status of this document at the time of
- its publication. Other documents may supersede this document. A list
- of current W3C publications and the latest revision of this technical
- report can be found in the <a href="http://www.w3.org/TR/">W3C technical
- reports index</a> at http://www.w3.org/TR/.
- </em></p><p>
- This document is the NaN @@ rypt <b>Candidate Recommendation</b> of the
- <cite>Web Cryptography API</cite> specification.
-
- Please send comments about this document to
- <a href="mailto:public-webcrypto-comments@w3.org">public-webcrypto-comments@w3.org</a>
- (<a href="http://lists.w3.org/Archives/Public/public-webcrypto-comments/">archived</a>).
- </p>
-
- <p>
- This document is produced by the <a href="http://www.w3.org/2012/webcrypto">Web Cryptography
- <acronym title="Working Group">WG</acronym></a> of the <acronym title="World Wide Web Consortium">W3C</acronym>.
- </p>
-
- <p class="XXX">
- Implementors should be aware that this specification is not stable.
- <strong>Implementors who are not taking part in the discussions are likely to find the
- specification changing out from under them in incompatible ways.</strong> Vendors interested
- in implementing this specification before it eventually reaches the Candidate Recommendation
- stage should join the mailing lists that follow and take part in the discussions.
- </p>
- <p>
- The Web Cryptography Working Group invites discussion and feedback on this draft document by
- web developers, companies, standardization bodies or forums interested in deployment of secure
- services with web applications. Specifically, Web Cryptography Working Group is looking for
- feedback on:
- </p>
- <ul>
- <li>developer convenience for managing keys and algorithms;</li>
- <li>comments on open issues the WG is currently dealing with, highlighted in this working draft;</li>
- <li>potential missing functionalities to deploy secure web applications.</li>
- </ul>
- <p>
- Previous discussion of this specification has taken place on three other
- mailing lists: <a href="mailto:whatwg@whatwg.org">whatwg@whatwg.org</a>
- (<a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031741.html">archive</a>)
- , <a href="mailto:public-websecurity@w3.org">public-websecurity@w3.org</a>
- (<a href="http://lists.w3.org/Archives/Public/public-web-security/2011Jun/0000.html">archive</a>), and
- <a href="mailto:public-identity@w3.org">public-identity@w3.org</a> (<a href="http://www.w3.org/Search/Mail/Public/search?type-index=public-identity&index-type=t&keywords=DOMCrypt&search=Search">archive</a>).
- Ongoing discussion will be on the <a href="mailto:public-webcrypto@w3.org">public-webcrypto@w3.org</a>
- mailing list.
- </p>
-
- <p>
- Web content and browser developers are encouraged to review this draft. Please send comments
- to <a href="mailto:public-webcrypto-comments@w3.org">public-webcrypto-comments@w3.org</a>,
- the <acronym title="World Wide Web Consortium">W3C</acronym>'s public email list for issues
- related to Web Cryptography. <a href="http://lists.w3.org/Archives/Public/public-webcrypto-comments/">Archives</a> of the
- public list and <a href="http://lists.w3.org/Archives/Public/public-webcrypto/">archives</a>
- of the member's-only list are available.
- </p>
- <p>
- Changes made to this document can be found in the
- <a href="https://dvcs.w3.org/hg/webcrypto-api/file/tip/spec/">W3C public Mercurial server</a>.
- </p>
-
- <p>
- Publication as a Candidate Recommendation does not imply endorsement by the
- W3C Membership. This is a draft document and may be updated, replaced
- or obsoleted by other documents at any time. It is inappropriate to cite
- this document as other than work in progress.
- </p><p>
- This document was produced by a group operating under the
- <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February
- 2004 W3C Patent Policy</a>. W3C maintains a
- <a href="http://www.w3.org/2004/01/pp-impl/54174/status">public list of
- any patent disclosures</a> made in connection with the deliverables of
- the group; that page also includes instructions for disclosing a patent.
- An individual who has actual knowledge of a patent which the individual
- believes contains
- <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential
- Claim(s)</a> must disclose the information in accordance with
- <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section
- 6 of the W3C Patent Policy</a>.
- </p>
- </div>
-
- <div id="toc">
- <h2>Table of Contents</h2>
- <div class="toc"><ul><li><a href="#introduction">1. Introduction</a></li><li><a href="#use-cases">2. Use Cases</a><ul><li><a href="#multifactor-authentication">2.1. Multi-factor Authentication</a></li><li><a href="#protected-document">2.2. Protected Document Exchange</a></li><li><a href="#cloud-storage">2.3. Cloud Storage</a></li><li><a href="#document-signing">2.4. Document Signing</a></li><li><a href="#data-integrity-protection">2.5. Data Integrity Protection</a></li><li><a href="#secure-messaging">2.6. Secure Messaging</a></li><li><a href="#jose">2.7. Javascript Object Signing and Encryption (JOSE)</a></li></ul></li><li><a href="#conformance">3. Conformance</a><ul><li><a href="#extensibility">3.1. Extensibility</a></li></ul></li><li><a href="#scope">4. Scope</a><ul><li><a href="#scope-abstraction">4.1. Level of abstraction</a></li><li><a href="#scope-algorithms">4.2. Cryptographic algorithms</a></li><li><a href="#scope-operations">4.3. Operations</a></li><li><a href="#scope-out-of-scope">4.4. Out of scope</a></li></ul></li><li><a href="#concepts">5. Concepts</a><ul><li><a href="#concepts-underlying-implementation">5.1. Underlying Cryptographic Implementation</a></li><li><a href="#concepts-key-storage">5.2. Key Storage</a></li></ul></li><li><a href="#security">6. Security considerations</a><ul><li><a href="#security-implementers">6.1. Security considerations for implementers</a></li><li><a href="#security-developers">6.2. Security considerations for authors</a></li><li><a href="#security-users">6.3. Security considerations for users</a></li></ul></li><li><a href="#privacy">7. Privacy considerations</a></li><li><a href="#dependencies">8. Dependencies</a></li><li><a href="#terminology">9. Terminology</a></li><li><a href="#crypto-interface">10. Crypto interface</a><ul><li><a href="#Crypto-description">10.1. Description</a></li><li><a href="#Crypto-interface-methods">10.2. Methods and Parameters</a><ul><li><a href="#Crypto-method-getRandomValues">10.2.1. The getRandomValues method</a></li></ul></li><li><a href="#Crypto-interface-attributes">10.3. Attributes</a><ul><li><a href="#Crypto-attribute-subtle">10.3.1. The subtle attribute</a></li></ul></li></ul></li><li><a href="#algorithm-dictionary">11. Algorithm dictionary</a><ul><li><a href="#algorithm-dictionary-members">11.1. Algorithm Dictionary Members</a></li></ul></li><li><a href="#key-algorithm-dictionary">12. KeyAlgorithm dictionary</a><ul><li><a href="#key-algorithm-dictionary-description">12.1. Description</a></li><li><a href="#key-algorithm-dictionary-members">12.2. KeyAlgorithm dictionary members</a></li></ul></li><li><a href="#cryptokey-interface">13. CryptoKey interface</a><ul><li><a href="#cryptokey-interface-description">13.1. Description</a></li><li><a href="#cryptokey-interface-types">13.2. Key interface data types</a></li><li><a href="#cryptokey-interface-internal-slots">13.3. CryptoKey internal slots</a></li><li><a href="#cryptokey-interface-members">13.4. CryptoKey interface members</a></li><li><a href="#cryptokey-interface-clone">13.5. Structured clone algorithm</a></li></ul></li><li><a href="#subtlecrypto-interface">14. SubtleCrypto interface</a><ul><li><a href="#subtlecrypto-interface-description">14.1. Description</a></li><li><a href="#subtlecrypto-interface-datatypes">14.2. Data Types</a></li><li><a href="#subtlecrypto-interface-methods">14.3. Methods and Parameters</a><ul><li><a href="#SubtleCrypto-method-encrypt">14.3.1. The encrypt method</a></li><li><a href="#SubtleCrypto-method-decrypt">14.3.2. The decrypt method</a></li><li><a href="#SubtleCrypto-method-sign">14.3.3. The sign method</a></li><li><a href="#SubtleCrypto-method-verify">14.3.4. The verify method</a></li><li><a href="#SubtleCrypto-method-digest">14.3.5. The digest method</a></li><li><a href="#SubtleCrypto-method-generateKey">14.3.6. The generateKey method</a></li><li><a href="#SubtleCrypto-method-deriveKey">14.3.7. The deriveKey method</a></li><li><a href="#SubtleCrypto-method-deriveBits">14.3.8. The deriveBits method</a></li><li><a href="#SubtleCrypto-method-importKey">14.3.9. The importKey method</a></li><li><a href="#SubtleCrypto-method-exportKey">14.3.10. The exportKey method</a></li><li><a href="#SubtleCrypto-method-wrapKey">14.3.11. The wrapKey method</a></li><li><a href="#SubtleCrypto-method-unwrapKey">14.3.12. The unwrapKey method</a></li></ul></li><li><a href="#SubtleCrypto-Exceptions">14.4. Exceptions</a></li></ul></li><li><a href="#JsonWebKey-dictionary">15. JsonWebKey dictionary</a></li><li><a href="#big-integer">16. BigInteger</a></li><li><a href="#keypair">17. CryptoKeyPair dictionary</a></li><li><a href="#algorithms">18. Algorithms</a><ul><li><a href="#algorithm-overview">18.1. Overview</a></li><li><a href="#algorithm-concepts">18.2. Concepts</a><ul><li><a href="#algorithm-concepts-naming">18.2.1. Naming</a></li><li><a href="#algorithm-concepts-operations">18.2.2. Supported Operations</a></li><li><a href="#algorithm-concepts-normalization">18.2.3. Normalization</a></li></ul></li><li><a href="#algorithm-conventions">18.3. Specification Conventions</a></li><li><a href="#algorithm-normalizing">18.4. Algorithm Normalization</a><ul><li><a href="#algorithm-normalizing-description">18.4.1. Description</a></li><li><a href="#algorithm-normalizing-internal">18.4.2. Internal State Objects</a></li><li><a href="#algorithm-normalizing-define-an-algorithm">18.4.3. Defining an Algorithm</a></li><li><a href="#algorithm-normalizing-normalize-an-algorithm">18.4.4. Normalizing an algorithm</a></li></ul></li><li><a href="#algorithm-recommendations">18.5. Recommendations</a><ul><li><a href="#algorithm-recommendations-authors">18.5.1. For Authors</a></li><li><a href="#algorithm-recommendations-implementers">18.5.2. For Implementers</a></li></ul></li></ul></li><li><a href="#algorithm-overview">19. Algorithm Overview</a></li><li><a href="#rsassa-pkcs1">20. RSASSA-PKCS1-v1_5</a><ul><li><a href="#rsassa-pkcs1-description">20.1. Description</a></li><li><a href="#rsassa-pkcs1-registration">20.2. Registration</a></li><li><a href="#RsaKeyGenParams-dictionary">20.3. RsaKeyGenParams dictionary</a></li><li><a href="#RsaHashedKeyGenParams-dictionary">20.4. RsaHashedKeyGenParams dictionary</a></li><li><a href="#RsaKeyAlgorithm-dictionary">20.5. RsaKeyAlgorithm dictionary</a></li><li><a href="#RsaHashedKeyAlgorithm-dictionary">20.6. RsaHashedKeyAlgorithm dictionary</a></li><li><a href="#RsaHashedImportParams-dictionary">20.7. RsaHashedImportParams dictionary</a></li><li><a href="#rsassa-pkcs1-operations">20.8. Operations</a></li></ul></li><li><a href="#rsa-pss">21. RSA-PSS</a><ul><li><a href="#rsa-pss-description">21.1. Description</a></li><li><a href="#rsa-pss-registration">21.2. Registration</a></li><li><a href="#RsaPssParams-dictionary">21.3. RsaPssParams dictionary</a></li><li><a href="#rsa-pss-operations">21.4. Operations</a></li></ul></li><li><a href="#rsa-oaep">22. RSA-OAEP</a><ul><li><a href="#rsa-oaep-description">22.1. Description</a></li><li><a href="#rsa-oaep-registration">22.2. Registration</a></li><li><a href="#rsa-oaep-params">22.3. RsaOaepParams dictionary</a></li><li><a href="#rsa-oaep-operations">22.4. Operations</a></li></ul></li><li><a href="#ecdsa">23. ECDSA</a><ul><li><a href="#ecdsa-description">23.1. Description</a></li><li><a href="#ecdsa-registration">23.2. Registration</a></li><li><a href="#EcdsaParams-dictionary">23.3. EcdsaParams dictionary</a></li><li><a href="#EcKeyGenParams-dictionary">23.4. EcKeyGenParams dictionary</a></li><li><a href="#EcKeyAlgorithm-dictionary">23.5. EcKeyAlgorithm dictionary</a></li><li><a href="#EcKeyImportParams-dictionary">23.6. EcKeyImportParams dictionary</a></li><li><a href="#ecdsa-operations">23.7. Operations</a></li></ul></li><li><a href="#ecdh">24. ECDH</a><ul><li><a href="#ecdh-description">24.1. Description</a></li><li><a href="#ecdh-registration">24.2. Registration</a></li><li><a href="#dh-EcdhKeyDeriveParams">24.3. EcdhKeyDeriveParams dictionary</a></li><li><a href="#ecdh-operations">24.4. Operations</a></li></ul></li><li><a href="#aes-ctr">25. AES-CTR</a><ul><li><a href="#aes-ctr-description">25.1. Description</a></li><li><a href="#aes-ctr-registration">25.2. Registration</a></li><li><a href="#aes-ctr-params">25.3. AesCtrParams dictionary</a></li><li><a href="#AesKeyAlgorithm-dictionary">25.4. </a></li><li><a href="#aes-keygen-params">25.5. AesKeyGenParams dictionary</a></li><li><a href="#aes-derivedkey-params">25.6. AesDerivedKeyParams dictionary</a></li><li><a href="#aes-ctr-operations">25.7. Operations</a></li></ul></li><li><a href="#aes-cbc">26. AES-CBC</a><ul><li><a href="#aes-cbc-description">26.1. Description</a></li><li><a href="#aes-cbc-registration">26.2. Registration</a></li><li><a href="#aes-cbc-params">26.3. AesCbcParams dictionary</a></li><li><a href="#aes-cbc-operations">26.4. Operations</a></li></ul></li><li><a href="#aes-cmac">27. AES-CMAC</a><ul><li><a href="#aes-cmac-description">27.1. Description</a></li><li><a href="#aes-cmac-registration">27.2. Registration</a></li><li><a href="#aes-cmac-params">27.3. AesCmacParams dictionary</a></li><li><a href="#aes-cmac-operations">27.4. Operations</a></li></ul></li><li><a href="#aes-gcm">28. AES-GCM</a><ul><li><a href="#aes-gcm-description">28.1. Description</a></li><li><a href="#aes-gcm-registration">28.2. Registration</a></li><li><a href="#aes-gcm-params">28.3. AesGcmParams dictionary</a></li><li><a href="#aes-gcm-operations">28.4. Operations</a></li></ul></li><li><a href="#aes-cfb">29. AES-CFB</a><ul><li><a href="#aes-cfb-description">29.1. Description</a></li><li><a href="#aes-cfb-registration">29.2. Registration</a></li><li><a href="#aes-cfb-params">29.3. AesCfbParams dictionary</a></li><li><a href="#aes-cfb-operations">29.4. Operations</a></li></ul></li><li><a href="#aes-kw">30. AES-KW</a><ul><li><a href="#aes-kw-description">30.1. Description</a></li><li><a href="#aes-kw-registration">30.2. Registration</a></li><li><a href="#aes-kw-operations">30.3. Operations</a></li></ul></li><li><a href="#hmac">31. HMAC</a><ul><li><a href="#hmac-description">31.1. Description</a></li><li><a href="#hmac-registration">31.2. Registration</a></li><li><a href="#hmac-importparams">31.3. HmacImportParams dictionary</a></li><li><a href="#HmacKeyAlgorithm-dictionary">31.4. HmacKeyAlgorithm dictionary</a></li><li><a href="#hmac-keygen-params">31.5. HmacKeyGenParams dictionary</a></li><li><a href="#hmac-operations">31.6. Operations</a></li></ul></li><li><a href="#dh">32. Diffie-Hellman</a><ul><li><a href="#dh-description">32.1. Description</a></li><li><a href="#dh-registration">32.2. Registration</a></li><li><a href="#dh-DhKeyGenParams">32.3. DhKeyGenParams dictionary</a></li><li><a href="#dh-DhKeyAlgorithm">32.4. DhKeyAlgorithm dictionary</a></li><li><a href="#dh-DhKeyDeriveParams">32.5. DhKeyDeriveParams dictionary</a></li><li><a href="#dh-DhImportKeyParams">32.6. DhImportKeyParams dictionary</a></li><li><a href="#dh-operations">32.7. Operations</a></li></ul></li><li><a href="#sha">33. SHA</a><ul><li><a href="#sha-description">33.1. Description</a></li><li><a href="#sha-registration">33.2. Registration</a></li><li><a href="#sha-operations">33.3. Operations</a></li></ul></li><li><a href="#concatkdf">34. Concat KDF</a><ul><li><a href="#concatkdf-description">34.1. Description</a></li><li><a href="#concatkdf-registration">34.2. Registration</a></li><li><a href="#concat-params">34.3. ConcatParams dictionary</a></li><li><a href="#concat-operations">34.4. Operations</a></li></ul></li><li><a href="#hkdf-ctr">35. HKDF-CTR</a><ul><li><a href="#hkdf-ctr-description">35.1. Description</a></li><li><a href="#hkdf-ctr-registration">35.2. Registration</a></li><li><a href="#hkdf-ctr-params">35.3. HkdfCtrParams dictionary</a></li><li><a href="#hkdf2-ctr-operations">35.4. Operations</a></li></ul></li><li><a href="#pbkdf2">36. PBKDF2</a><ul><li><a href="#pbkdf2-description">36.1. Description</a></li><li><a href="#pbkdf2-registration">36.2. Registration</a></li><li><a href="#pbkdf2-params">36.3. Pbkdf2Params dictionary</a></li><li><a href="#pbkdf2-operations">36.4. Operations</a></li></ul></li><li><a href="#examples-section">37. JavaScript Example Code</a><ul><li><a href="#examples-signing">37.1. Generate a signing key pair, sign some data</a></li><li><a href="#examples-symmetric-encryption">37.2. Symmetric Encryption</a></li></ul></li><li><a href="#iana-section">38. IANA Considerations</a><ul><li><a href="#iana-section-jws-jwa">38.1. JSON Web Signature and Encryption Algorithms Registration</a></li><li><a href="#iana-section-jwk">38.2. JSON Web Key Parameters Registration</a></li></ul></li><li><a href="#acknowledgements-section">39. Acknowledgements</a></li><li><a href="#references">40. References</a><ul><li><a href="#normative-references">40.1. Normative References</a></li><li><a href="#informative-references">40.2. Informative References</a></li></ul></li></ul><ul><li><a href="#jwk-mapping">A. Mapping between JSON Web Key / JSON Web Algorithm</a><ul><li><a href="#jwk-mapping-alg">A.1. Algorithm mappings</a></li><li><a href="#jwk-mapping-usage">A.2. Usage mapping</a></li></ul></li><li><a href="#spki-mapping">B. Mapping between Algorithm and SubjectPublicKeyInfo</a></li><li><a href="#pkcs8-mapping">C. Mapping between Algorithm and PKCS#8 PrivateKeyInfo</a></li></ul></div>
- </div>
-
- <div id="sections">
- <div id="introduction" class="section">
- <h2>1. Introduction</h2>
- <p class="norm">This section is non-normative.</p>
- <p>
- The Web Cryptography API defines a low-level interface to interacting with cryptographic
- key material that is managed or exposed by user agents. The API itself is agnostic of
- the underlying implementation of key storage, but provides a common set of interfaces
- that allow rich web applications to perform operations such as signature generation and
- verification, hashing and verification, encryption and decryption, without requiring
- access to the raw keying material.
- </p>
- <p>
- Cryptographic transformations are exposed via the
- <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface, which defines a common set
- of methods and events for dealing with initialization, processing data, and completing
- the operation to yield the final output. In addition to operations such as signature
- generation and verification, hashing and verification, and encryption and decryption,
- the API provides interfaces for key generation, key derivation, key import and export,
- and key discovery.
- </p>
- </div>
-
- <div id="use-cases" class="section">
- <h2>2. Use Cases</h2>
- <p class="norm">This section is non-normative</p>
- <div id="multifactor-authentication" class="section">
- <h3>2.1. Multi-factor Authentication</h3>
- <p>
- A web application may wish to extend or replace existing username/password based
- authentication schemes with authentication methods based on proving that the user has
- access to some secret keying material. Rather than using transport-layer authentication,
- such as TLS client certificates, the web application may wish to provide a rich user
- experience by providing authentication within the application itself.
- </p>
- <p>
- Using the Web Cryptography API, such an application could locate suitable client keys,
- which may have been previously generated via the user agent or pre-provisioned
- out-of-band by the web application. It could then perform cryptographic operations such
- as decrypting an authentication challenge followed by signing an authentication response.
- </p>
- <p>
- Further, the authentication data could be further enhanced by binding the authentication
- to the TLS session that the client is authenticating over, by deriving a key based on
- properties of the underlying transport.
- </p>
- <p>
- If a user did not already have a key associated with their account, the web application
- could direct the user agent to either generate a new key or to re-use an existing key of
- the user's choosing.
- </p>
- </div>
-
- <div id="protected-document" class="section">
- <h3>2.2. Protected Document Exchange</h3>
- <p>
- When exchanging documents that may contain sensitive or personal information, a
- web application may wish to ensure that only certain users can view the documents, even
- after they have been securely received, such as over TLS. One way that a web application
- can do so is by encrypting the documents with a secret key, and then wrapping that key
- with the public keys associated with authorized users.
- </p>
- <p>
- When a user agent navigates to such a web application, the application may send the
- encrypted form of the document. The user agent is then instructed to unwrap the encryption
- key, using the user's private key, and from there, decrypt and display the document.
- </p>
- </div>
-
- <div id="cloud-storage" class="section">
- <h3>2.3. Cloud Storage</h3>
- <p>
- When storing data with remote service providers, users may wish to protect the
- confidentiality of their documents and data prior to uploading them. The Web
- Cryptography API allows an application to have a user select a private or secret key,
- to either derive encryption keys from the selected key or to directly encrypt documents
- using this key, and then to upload the transformed/encrypted data to the service provider
- using existing APIs.
- </p>
- <p>
- This use case is similar to the <a href="#protected-document">Protected Document
- Exchange</a> use case because Cloud Storage can be considered as a user exchanging
- protected data with himself in the future.
- </p>
- </div>
-
- <div id="document-signing" class="section">
- <h3>2.4. Document Signing</h3>
- <p>
- A web application may wish to accept electronic signatures on documents, in lieu of
- requiring physical signatures. An authorized signature may use a key that was
- pre-provisioned out-of-band by the web application, or it may be using a key that the
- client generated specifically for the web application.
- </p>
- <p>
- The web application must be able to locate any appropriate keys for signatures, then
- direct the user to perform a signing operation over some data, as proof that they accept
- the document.
- </p>
- </div>
-
- <div id="data-integrity-protection" class="section">
- <h3>2.5. Data Integrity Protection</h3>
- <p>
- When caching data locally, an application may wish to ensure that this data cannot be
- modified in an offline attack. In such a case, the server may sign the data that it
- intends the client to cache, with a private key held by the server. The web application
- that subsequently uses this cached data may contain a public key that enables it to
- validate that the cache contents have not been modified by anyone else.
- </p>
- </div>
-
- <div id="secure-messaging" class="section">
- <h3>2.6. Secure Messaging</h3>
- <p>
- In addition to a number of web applications already offering chat based services, the
- rise of WebSockets and RTCWEB allows a great degree of flexibility in inter-user-agent
- messaging. While TLS/DTLS may be used to protect messages to web applications, users
- may wish to directly secure messages using schemes such as off-the-record (OTR) messaging.
- </p>
- <p>
- The Web Cryptography API enables OTR, by allowing key agreement to be performed so that
- the two parties can negotiate shared encryption keys and message authentication code (MAC)
- keys, to allow encryption and decryption of messages, and to prevent tampering of
- messages through the MACs.
- </p>
- </div>
-
- <div id="jose" class="section">
- <h3>2.7. Javascript Object Signing and Encryption (JOSE)</h3>
- <p>
- A web application wishes to make use of the structures and format of
- messages defined by the IETF Javascript Object Signing and Encryption
- (JOSE) Working Group. The web application wishes to manipulate public
- keys encoded in the JSON key format (JWK), messages that have been
- integrity protected using digital signatures or MACs (JWS), or that
- have been encrypted (JWE).
- </p>
- </div>
-
- </div>
-
- <div id="conformance" class="section">
- <h2>3. Conformance</h2>
- <p>
- As well as sections marked as non-normative, all authoring guidelines, diagrams,
- examples, and notes in this specification are non-normative. Everything else in
- this specification is normative.
- </p>
- <p>
- The keywords <span class="RFC2119">MUST</span>,
- <span class="RFC2119">MUST NOT</span>,
- <span class="RFC2119">REQUIRED</span>,
- <span class="RFC2119">SHALL</span>,
- <span class="RFC2119">SHALL NOT</span>,
- <span class="RFC2119">RECOMMENDED</span>,
- <span class="RFC2119">MAY</span>,
- <span class="RFC2119">OPTIONAL</span>,
- in this specification are to be interpreted as described in
- <cite><a href="http://www.ietf.org/rfc/rfc2119">Key words for use in RFCs to
- Indicate Requirement Levels</a></cite> [<a href="#RFC2119">RFC2119</a>].
- </p>
- <p>
- The following conformance classes are defined by this specification:
- </p>
- <dl>
- <dt><dfn id="dfn-conforming-implementation">conforming user agent</dfn></dt>
- <dd>
- <p>
- A user agent is considered to be a
- <a class="dfnref" href="#dfn-conforming-implementation">conforming user agent</a>
- if it satisfies all of the <span class="RFC2119">MUST</span>-,
- <span class="RFC2119">REQUIRED</span>- and <span class="RFC2119">SHALL</span>-level
- criteria in this specification that apply to implementations. This specification
- uses both the terms "conforming user agent" and "user agent" to refer to this
- product class.
- </p>
- </dd>
- </dl>
- <p>
- Conformance requirements phrased as algorithms or specific steps may be implemented in any
- manner, so long as the end result is equivalent. (In particular, the algorithms defined in
- this specification are intended to be easy to follow, and not intended to be performant.)
- </p>
- <p>
- User agents that use ECMAScript to implement the APIs defined in this specification
- <span class="RFC2119">MUST</span> implement them in a manner consistent with the
- ECMAScript Bindings defined in the Web IDL specification [<a href="#WebIDL">WEBIDL</a>]
- as this specification uses that specification and terminology.
- </p>
- <p>
- Unless otherwise stated, string comparisons are done in a
- <a href="#case-sensitive">case-sensitive</a> manner. String literals in this specification
- written in monospace font like <code>"this"</code> do not include the enclosing quotes.
- </p>
- <div id="extensibility" class="section">
- <h3>3.1. Extensibility</h3>
- <p>
- Vendor-specific proprietary extensions to this specification are strongly discouraged.
- Authors must not use such extensions, as doing so reduces interoperability and fragments
- the user base, allowing only users of specific user agents to access the content in
- question.
- </p>
- <p>
- If vendor-specific extensions are needed, the members should be prefixed by
- vendor-specific strings to prevent clashes with future versions of this specification.
- Extensions must be defined so that the use of extensions neither contradicts nor causes
- the non-conformance of functionality defined in the specification.
- </p>
- <p>
- When vendor-neutral extensions to this specification are needed, either this
- specification can be updated accordingly, or an extension specification can be written
- that overrides the requirements in this specification. When someone applying this
- specification to their activities decides that they will recognize the requirements of
- such an extension specification, it becomes an
- <dfn id="dfn-applicable-specification">applicable specification</dfn> for the purposes
- of conformance requirements in this specification. Applicable specifications defined
- by the W3C WebCrypto Working Group are listed in the table below.
- </p>
- <p>
- <table>
- <tbody>
- <tr>
- <td>Specification</td>
- <td>Reference</td>
- </tr>
- </tbody>
- </table>
- </p>
- <div class="note"><div class="noteHeader">Note</div>
- Readers are advised to consult the errata to this specification for updates to the table
- above.
- </div>
- </div>
- </div>
-
- <div id="scope" class="section">
- <h2>4. Scope</h2>
- <p class="norm">This section is non-normative.</p>
- <div class="section" id="scope-abstraction">
- <h3>4.1. Level of abstraction</h3>
- <p>
- The specification attempts to focus on the common functionality and features between
- various platform-specific or standardized cryptographic APIs, and avoid features and
- functionality that are specific to one or two implementations. As such this API allows
- key generation, management, and exchange with a level of abstraction that avoids
- developers needing to care about the implementation of the underlying key storage. The
- API is focused specifically around CryptoKey objects, as an abstraction for the
- underlying raw cryptographic keying material. The intent behind this is to allow an API
- that is generic enough to allow conforming user agents to expose keys that are stored
- and managed directly by the user agent, that may be stored or managed using isolated
- storage APIs such as per-user key stores provided by some operating systems, or within
- key storage devices such as secure elements, while allowing rich web applications to
- manipulate the keys and without requiring the web application be aware of the nature of
- the underlying key storage.
- </p>
- </div>
- <div class="section" id="scope-algorithms">
- <h3>4.2. Cryptographic algorithms</h3>
- <p>
- Because the underlying cryptographic implementations will vary between conforming user
- agents, and may be subject to local policy, including but not limited to concerns such
- as government or industry regulation, security best practices, intellectual property
- concerns, and constrained operational environments, this specification does not dictate
- a mandatory set of algorithms that <span class="RFC2119">MUST</span> be implemented.
- Instead, it defines a common set of bindings that can be used in an
- algorithm-independent manner, a common framework for discovering if a user agent or key
- handle supports the underlying algorithm, and a set of conformance requirements for the
- behaviours of individual algorithms, if implemented.
- </p>
- </div>
- <div class="section" id="scope-operations">
- <h3>4.3. Operations</h3>
- <p>
- Although the API does not expose the notion of cryptographic providers or modules, each
- key is internally bound to a cryptographic provider or module, so web applications can
- rest assured that the right cryptographic provider or module will be used to perform
- cryptographic operations involving that key.
- </p>
- </div>
- <div class="section" id="scope-out-of-scope">
- <h3>4.4. Out of scope</h3>
- <p>
- This API, while allowing applications to generate, retrieve, and manipulate keying
- material, does not specifically address the provisioning of keys in particular types of
- key storage, such as secure elements or smart cards. This is due to such provisioning
- operations often being burdened with vendor-specific details that make defining a
- vendor-agnostic interface an unsuitably unbounded task. Additionally, this API does not
- deal with or address the discovery of cryptographic modules, as such concepts are
- dependent upon the underlying user agent and are not concepts that are portable between
- common operating systems, cryptographic libraries, and implementations.
- </p>
- </div>
- </div>
-
-
- <div class="section" id="concepts">
- <h2>5. Concepts</h2>
- <p class="norm">This section is non-normative.</p>
- <div class="section" id="concepts-underlying-implementation">
- <h3>5.1. Underlying Cryptographic Implementation</h3>
- <p>
- This specification assumes, but does not require, that conforming user agents do not
- and will not be directly implementing cryptographic operations within the user agent
- itself. Historically, many user agents have deferred cryptographic operations, such as
- those used within TLS, to existing APIs that are available as part of the underlying
- operating system or to third-party modules that are managed independently of the user
- agent.
- </p>
- <p>
- The <a href="#dfn-CryptoKey">CryptoKey</a> object represents the bridge between the
- JavaScript execution environment and these underlying libraries, through the use of the
- internal slot named [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]. The handle
- represents an opaque type that is implementation specific, which may not be represented
- within a JavaScript type, nor is it ever exposed to script authors. In this way, the
- <a href="#dfn-CryptoKey">CryptoKey</a> object is the conceptual equivalent to the
- JavaScript executing environment as the
- [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] is to the underlying cryptographic
- implementation.
- </p>
- <p>
- These APIs are traditionally built around a notion of cryptographic providers, an
- abstraction for a specific implementation of a set of algorithms. The operating system
- or library may come with a default provider, and users are frequently allowed to add
- additional providers, reconfigure the set of enabled algorithms, or otherwise customize
- how cryptographic services are provided.
- </p>
- <p>
- While it is assumed that most user agents will be interacting with a cryptographic
- provider that is implemented purely in software, it is not required by this
- specification. As a result, the capabilities of some implementations may be limited by
- the capabilities of the underlying hardware, and, depending on how the user has
- configured the underlying cryptographic library, this may be entirely opaque to the
- User Agent.
- </p>
- </div>
- <div class="section" id="concepts-key-storage">
- <h3>5.2. Key Storage</h3>
- <p>
- This specification does not explicitly provide any new storage mechanisms for
- <a href="#dfn-CryptoKey">CryptoKey</a> objects. Instead, by allowing the
- <a href="#dfn-CryptoKey">CryptoKey</a> to be used with the structured clone algorithm,
- any existing or future web storage mechanisms that support storing structured clonable
- objects can be used to store <a href="#dfn-CryptoKey">CryptoKey</a> objects.
- </p>
- <p>
- In practice, it is expected that most authors will make use of the
- <a href="#IndexedDB">Indexed Database API</a>, which allows associative storage of
- key/value pairs, where the key is some string identifier meaningful to the application,
- and the value is a <a href="#dfn-CryptoKey">CryptoKey</a> object. This allows the
- storage and retrieval of key material, without ever exposing that key material to the
- application or the JavaScript environment. Additionally, this allows authors
- the full flexibility to store any additional metadata with the
- <a href="#dfn-CryptoKey">CryptoKey</a> itself.
- </p>
- </div>
- </div>
-
- <div id="security" class="section">
- <h2>6. Security considerations</h2>
- <p class="norm">This section is non-normative.</p>
- <div id="security-implementers" class="section">
- <h2>6.1. Security considerations for implementers</h2>
- <p>
- By not providing an explicit storage mechanism, this specification assumes that
- <a href="#dfn-CryptoKey">CryptoKey</a> objects are scoped to the current execution
- environment and any storage mechanisms available to that environment (e.g.
- <a href="#IndexedDB">Indexed Database API</a>). Application authors rely upon this for
- the security of their applications; two origins with the same
- <a href="#dfn-CryptoKey">CryptoKey</a> object have full access to the underlying key,
- and as such, messages from these applications cannot be distinguished, and messages sent
- to these applications can be fully recovered. Implementors should ensure that no
- <a href="#dfn-CryptoKey">CryptoKey</a> objects are shared between two origins unless
- the author has explicitly chosen to share (e.g., such as through the use of postMessage)
- </p>
- <p>
- A number of algorithms specified within this specification perform computationally
- intensive work, such as the generation of significantly large prime numbers, or through
- repeated iterations of a particular operation. As such, hostile applications may attempt
- to misuse this API and attempt to cause significant amount of work to be performed by
- an implementation, denying access or services to other applications that are executing.
- Implementations should take steps to mitigate these risks, such as limiting the amount
- of operations an implementation performs concurrently, requiring user consent for
- operations that may be known to be disruptive for the executing environment, or defining
- device-specific limits on attributes such as key sizes or iteration counts.
- </p>
- </div>
- <div id="security-developers" class="section">
- <h2>6.2. Security considerations for authors</h2>
- <p>
- This specification includes descriptions for a variety of cryptographic operations, some
- of which have known weaknesses when used inappropriately. Application developers must
- take care and review appropriate and current cryptographic literature, to understand and
- mitigate such issues. In general, application developers are <strong>strongly</strong>
- discouraged from inventing new cryptographic protocols; as with all applications, users
- of this specification will be best served through the use of existing protocols, of
- which this specification provides the necessary building blocks to implement.
- </p>
- <p>
- In order to use the APIs defined in this specification to provide any meaningful
- cryptographic assurances, authors must be familiar with existing threats to web
- applications, as well as the underlying security model employed. Conceptually, issues
- such as script injection are the equivalent to remote code execution in other operating
- environments, and allowing hostile script to be injected may allow for the exfiltration
- of keys or data. Script injection may come from other applications, for which the
- judicious use of Content Security Policy may mitigate, or it may come from hostile
- network intermediaries, for which the use of Transport Layer Security may mitigate.
- </p>
- <p>
- This specification does not define any specific mechanisms for the storage of
- cryptographic keys. By default, unless specific effort is taken by the author to persist
- keys, such as through the use of the <a href="#IndexedDB">Indexed Database API</a>, keys
- created with this API will only be valid for the duration of the current page (e.g.
- until a navigation event). Authors that wish to use the same key across different pages
- or multiple browsing sessions must employ existing web storage technologies. Authors
- should be aware of the security assumptions of these technologies, such as the
- same-origin security model; that is, any application that shares the same scheme, host,
- and port have access to the same storage partition, even if other information, such as
- the path, may differ. Authors may explicitly choose to relax this security through the
- use of inter-origin sharing, such as <code>postMessage</code>.
- </p>
- <p>
- Authors should be aware that this specification places no normative requirements on
- implementations as to how the underlying cryptographic key material is stored. The only
- requirement is that key material is not exposed to script, except through the use of the
- <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> and <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a> operations. In particular, it does
- not guarantee that the underlying cryptographic key material will not be persisted to
- disk, possibly unencrypted, nor that it will be inaccessible to users or other
- applications running with the same privileges as the User Agent. Any application or user
- that has access to the device storage may be able to recover the key material, even
- through scripts may be prohibited.
- </p>
- <p>
- This specification places no normative requirements on how implementations handle key
- material once all references to it go away. That is, conforming user agents are not
- required to zeroize key material, and it may still be accessible on device storage or
- device memory, even after all references to the <a href="#dfn-CryptoKey">CryptoKey</a>
- have gone away.
- </p>
- <p>
- Applications may share a <a href="#dfn-CryptoKey">CryptoKey</a> object across security
- boundaries, such as origins, through the use of the structured clone algorithm and APIs
- such as <code>postMessage</code>. While access to the underlying cryptographic key
- material may be restricted, based upon the <a href="#dfn-CryptoKey-extractable">extractable</a>
- attribute, once a key is shared with a destination origin, the source origin can not
- later restrict or revoke access to the key. As such, authors must be careful to ensure
- they trust the destination origin to take the same mitigations against hostile script
- that the source origin employs. Further, in the event of script injection on the source
- origin, attackers may post the key to an origin under attacker control. Any time that
- the user agent visits the attacker's origin, the user agent may be directed to perform
- cryptographic operations using that key, such as the decryption of existing messages
- or the creation of new, fraudulent messages.
- </p>
- <p>
- Authors should be aware that users may, at any time, choose to clear the storage
- associated with an origin, potentially destroying keys. Applications that are meant to
- provide long-term storage, such as on the server, should consider techniques such as
- key escrow to prevent such data from being inaccessible. Authors should not presume
- that keys will be available indefinitely.
- </p>
- </div>
- <div class="section" id="security-users">
- <h3>6.3. Security considerations for users</h3>
- <p>
- Users of applications that employ the APIs defined in this specification should be aware
- that these applications will have full access to all messages exchanged, regardless of
- the cryptography employed. That is, for messages that are encrypted, applications that
- use these APIs will have full access to the decrypted message as well.
- </p>
- </div>
- </div>
-
- <div id="privacy" class="section">
- <h2>7. Privacy considerations</h2>
- <p class="norm">This section is non-normative.</p>
- <dl>
- <dt>Fingerprinting</dt>
- <dd>
- By exposing additional APIs that reflect capabilities of the underlying platform, this
- specification may allow malicious applications to determine or distinguish different
- user agents or devices.
- </dd>
- <dt>Super-cookies</dt>
- <dd>
- This specification does not provide any means for malicious applications to create
- identifiers that outlive existing web storage technologies. However, care must be taken
- when introducing future revisions to this API or additional cryptographic capabilities,
- such as those that are hardware backed (e.g.: smart cards or Trusted Platform Modules).
- Considering that such storage is designed to prevent any two users from having the same
- underlying key data, such APIs may represent a real risk of being used as a permanent
- identifier against the user's wishes.
- </dd>
- </dl>
- </div>
-
- <div id="dependencies" class="section">
- <h3>8. Dependencies</h3>
- <p>This specification relies on underlying specifications.</p>
- <dl>
- <dt>DOM</dt>
- <dd>
- <p>
- A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST support at
- least the subset of the functionality defined in DOM4 that this specification relies
- upon; in particular, it MUST support <code>Promises</code> and
- <dfn id="dfn-DOMException">DOMException</dfn>.
- [<a href="#DOM4">DOM4</a>]
- </p>
- </dd>
- <dt>HTML</dt>
- <dd>
- <p>
- A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST support at
- least the subset of the functionality defined in HTML that this specification relies
- upon; in particular, it MUST support the
- <a href="#arraybufferview">ArrayBufferView</a> typedef and the
- <a href="#structured-clone">structured clone</a> algorithm.
- [<a href="#HTML">HTML</a>]
- </p>
- </dd>
- <dt>Web IDL</dt>
- <dd>
- <p>
- A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST be a
- conforming implementation of the IDL fragments in this specification, as described in
- the Web IDL specification. [<a href="#WebIDL">WEBIDL</a>]
- </p>
- </dd>
- </dl>
- </div>
-
- <div id="terminology" class="section">
- <h2>9. Terminology</h2>
- <p>
- The terms and algorithms
- <dfn id="arraybufferview">ArrayBufferView</dfn>, and
- <dfn id="structured-clone">structured clone</dfn>,
- are defined by the HTML specification [<a href="#HTML">HTML</a>].
- </p>
- <p>
- The term <dfn id="BufferSource">BufferSource</dfn> is defined in [<cite><a href="#WebIDL">WEBIDL</a></cite>].
- </p>
- <p>
- An <dfn id="dfn-octet-string">octet string</dfn> is an ordered sequence of zero or more
- integers, each in the range 0 to 255 inclusive.
- </p>
- <p>
- Comparing two strings in a <dfn id="case-sensitive">case-sensitive</dfn>
- manner means comparing them exactly, code point for code point.
- </p>
- <p>
- Comparing two strings in a <dfn id="case-insensitive">ASCII case-insensitive</dfn> manner
- means comparing them exactly, code point for code point, except that the codepoints in
- the range U+0041 .. U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) and
- the corresponding codepoints in the range U+0061 .. U+007A
- (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z) are also considered to match.
- </p>
- <p>
- When this specification says to <dfn id="terminate-the-algorithm">terminate the
- algorithm</dfn>, the user agent must terminate the algorithm after finishing the step it
- is on. The algorithm referred to is the set of specification-defined processing steps,
- rather than the underlying cryptographic algorithm that may be in the midst of processing.
- </p>
- <p>
- When this specification says to <dfn id="concept-parse-an-asn1-structure">parse an ASN.1
- structure</dfn>, the user agent must perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>data</var> be a sequence of bytes to be parsed.
- </p>
- </li>
- <li>
- <p>
- Let <var>structure</var> be the ASN.1 structure to be parsed.
- </p>
- </li>
- <li>
- <p>
- Let <var>exactData</var> be an optional boolean value. If it is not supplied,
- let it be initialized to <code>true</code>.
- </p>
- </li>
- <li>
- <p>
- Parse <var>data</var> according to the Distinguished Encoding Rules of
- <a href="#X690">X.690 (11/08)</a>, using <var>structure</var> as the ASN.1 structure
- to be decoded.
- </p>
- </li>
- <li>
- <p>
- If <var>exactData</var> was specified, and all of the bytes of <var>data</var> were
- not consumed during the parsing phase, then
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the parsed ASN.1 structure.
- </p>
- </li>
- </ol>
- <p>
- When this specification says to <dfn id="concept-parse-a-spki">parse a
- subjectPublicKeyInfo</dfn>, the user agent must
- <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>, with
- <var>data</var> set to the sequence of bytes to be parsed, <var>structure</var> as the
- ASN.1 structure of subjectPublicKeyInfo, as specified in <a href="#RFC5280">RFC 5280</a>,
- and <var>exactData</var> set to <code>true</code>.
- </p>
- <p>
- When this specification says to <dfn id="concept-parse-a-privateKeyInfo">parse a
- PrivateKeyInfo</dfn>, the user agent must <a href="#concept-parse-an-asn1-structure">parse
- an ASN.1 structure</a> with <var>data</var> set to the sequence of bytes to be parsed,
- <var>structure</var> as the ASN.1 structure of PrivateKeyInfo, as specified in
- <a href="#RFC5208">RFC 5208</a>, and <var>exactData</var> set to <code>true</code>.
- </p>
- <p>
- When this specification says to <dfn id="concept-parse-a-jwk">parse a JWK</dfn>, the user
- agent must run the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the sequence of bytes to be parsed.
- </p>
- </li>
- <li>
- <p>
- Let <var>json</var> be the Unicode string that results from interpreting
- <var>data</var> according to UTF-8.
- </p>
- </li>
- <li>
- <p>
- Convert <var>json</var> to UTF-16.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the object literal that results from executing the
- <code>JSON.parse</code> internal function, with <code>text</code>
- argument set to a JavaScript String containing <var>json</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be the result of converting <var>result</var> to the IDL dictionary
- type of <a href="#dfn-JsonWebKey">JsonWebKey</a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>key</var> is not defined, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- <p>
- When this specification says to <dfn id="concept-clone-BufferSource">clone the
- data</dfn> of a <a href="http://heycam.github.io/webidl/#common-BufferSource">BufferSource</a> object
- <var>data</var>, the user agent must run the following steps:
- </p>
- <dl class="switch">
- <dt>
- If <var>data</var> is an <code>ArrayBuffer</code>:
- </dt>
- <dd>
- Return the result of invoking the <code>ArrayBuffer.prototype.slice</code> method on
- <var>data</var>, with the <var>start</var> value set to the integer 0, and the
- <var>end</var> value set to the value of the [[ArrayBufferByteLength]] internal slot
- of <var>data</var>.
- </dd>
- <dt>
- If <var>data</var> is an <code>ArrayBufferView</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>buffer</var> be the value of the [[ViewedArrayBuffer]] internal slot
- of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>start</var> be the value of the [[ByteOffset]] internal slot of
- <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>end</var> be the value of the [[ByteLength]] internal slot of
- <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>relativeEnd</var> be <var>start</var>+<var>end</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of invoking the <code>ArrayBuffer.prototype.slice</code> method
- on <var>buffer</var>, with the <var>start</var> value set to <var>start</var> and
- the <var>end</var> value set to <var>relativeEnd</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- The above definition makes heavy use of directly accessing the internal slot values,
- defined in <a href="#ECMA-262">ECMA262</a>. The motivation for this is to avoid issues
- that might arise with authors defining custom getters/setters on such objects. However,
- it has the downside of avoiding the error control statements defined in the
- <code>%TypedArray%.prototype</code> getters and <code>ArrayBuffer.prototype</code>
- getters, which would be desirable.
- </p>
- <p>
- It is assumed that the Web IDL conversion rules will perform the necessary type checks,
- and that as a result of these checks, it is guaranteed that the internal slots will
- always have valid values for the above algorithm. However, that assumption may not be
- safe to make.
- </p>
- </div>
- <p>
- When this specification states to supply the <dfn id="concept-contents-of-arraybuffer">
- contents of an ArrayBuffer</dfn> named <var>data</var> to an underlying cryptographic
- implementation, the User Agent shall supply a contiguous sequence of bytes that is equal
- to the contents of the Data Block value of the [[ArrayBufferData]] internal slot of
- <var>data</var>, and whose length in bytes is equal to the [[ArrayBufferByteLength]]
- internal slot of <var>data</var>.
- </p>
- <p>
- When this specification says to calculate the <dfn id="concept-usage-intersection">usage
- intersection</dfn> of two sequences, <var>a</var> and <var>b</var> the result shall be a
- sequence containing each <a href="#dfn-RecognizedKeyUsage">recognized key usage value</a>
- that appears in both <var>a</var> and <var>b</var>, in the order listed in the list of
- <a href="#dfn-RecognizedKeyUsage">recognized key usage values</a>, where a value is said
- to appear in a sequence if an element of the sequence exists that is a case-sensitive string
- match for that value.
- </p>
- <p>
- When this specification says to calculate the <dfn id="concept-normalized-usages">
- normalized value of a usages list</dfn>, <var>usages</var> the result shall be the
- <a href="#concept-usage-intersection">usage intersection</a> of <var>usages</var> and a
- sequence containing all <a href="#dfn-RecognizedKeyUsage">recognized key usage values</a>.
- </p>
- <p>
- When this specification refers to the <dfn id="concept-cached-object">cached ECMAScript
- object</dfn> associated with an internal slot [[<var>slot</var>]] of <var>object</var>,
- the user agent must run the following steps:
- </p>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the [[<var>slot</var>_cached]] internal slot of <var>object</var> is undefined:
- </dt>
- <dd>
- Set the [[<var>slot</var>_cached]] internal slot of <var>object</var> to the result
- of performing type conversion to an ECMAScript object as defined in
- [<a href="#WebIDL">WEBIDL</a>] to the contents of the [[<var>slot</var>]]
- internal slot of <var>object</var>.
- </dd>
- </dl>
- </li>
- <li>
- Return the contents of the [[<var>slot</var>_cached]] internal slot of <var>object</var>.
- </li>
- </ol>
- </div>
-
- <div id="crypto-interface" class="section">
- <h2>10. Crypto interface</h2>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-[NoInterfaceObject]
-interface <dfn id="dfn-GlobalCrypto">GlobalCrypto</dfn> {
- readonly attribute <a href="#dfn-Crypto">Crypto</a> crypto;
-};
-
-Window implements GlobalCrypto;
-WorkerGlobalScope implements GlobalCrypto;
-
-[Exposed=(Window,Worker)]
-interface <dfn id="dfn-Crypto">Crypto</dfn> {
- readonly attribute <a href="#dfn-SubtleCrypto">SubtleCrypto</a> subtle;
- ArrayBufferView <a href="#dfn-Crypto-method-getRandomValues">getRandomValues</a>(ArrayBufferView array);
-};
- </code></pre></div></div>
-
- <div id="Crypto-description" class="section">
- <h3>10.1. Description</h3>
- <p>
- The <a href="#dfn-Crypto">Crypto</a> interface represents an interface to
- general purpose cryptographic functionality including a
- cryptographically strong pseudo-random number generator seeded with truly random values.
- </p>
- <div class="note"><div class="noteHeader">Note</div>
- Implementations should generate cryptographically random values using
- well-established cryptographic pseudo-random number generators seeded with high-quality
- entropy, such as from an operating-system entropy source (e.g., "/dev/urandom"). This
- specification provides no lower-bound on the information theoretic entropy present in
- cryptographically random values, but implementations should make a best effort to provide
- as much entropy as practicable.
- </div>
- <div class="note"><div class="noteHeader">Note</div>
- This interface defines a synchronous method for obtaining cryptographically random
- values. While some devices and implementations may support truly random cryptographic
- number generators or provide interfaces that block when there is insufficient entropy,
- implementations are discouraged from using these sources when implementing
- getRandomValues, both for performance and to avoid depleting the system of entropy.
- Instead, these sources should be used to seed a cryptographic pseudo-random number
- generator that can then return suitable values efficiently.
- </div>
- </div>
- <div id="Crypto-interface-methods" class="section">
- <h3>10.2. Methods and Parameters</h3>
- <div id="Crypto-method-getRandomValues" class="section">
- <h4>10.2.1. The getRandomValues method</h4>
- <p>
- The <dfn id="dfn-Crypto-method-getRandomValues"><code>getRandomValues</code></dfn>
- method generates cryptographically random values. It must act as follows:
- </p>
- <ol>
- <li>
- <p>
- If <var>array</var> is not of an integer type (i.e., Int8Array, Uint8Array,
- Int16Array, Uint16Array, Int32Array, or Uint32Array), <a href="#concept-throw">throw</a> a
- <code>TypeMismatchError</code> and
- <a href="#terminate-the-algorithm">terminate the algorithm</a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>byteLength</code> of <var>array</var> is greater than 65536, <a href="#concept-throw">throw</a> a
- <code>QuotaExceededError</code> and
- <a href="#terminate-the-algorithm">terminate the algorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Overwrite all elements of <var>array</var> with cryptographically random values of
- the appropriate type.
- </p>
- </li>
- <li>
- <p>
- Return <var>array</var>.
- </p>
- </li>
- </ol>
- <div class="note"><div class="noteHeader">Note</div>
- <p>
- Do not generate keys using the <code>getRandomValues</code> method. Use the
- <a href="#dfn-SubtleCrypto-method-generateKey"><code>generateKey</code></a> method
- instead.
- </p>
- </div>
- </div>
- </div>
- <div id="Crypto-interface-attributes" class="section">
- <h3>10.3. Attributes</h3>
- <div id="Crypto-attribute-subtle" class="section">
- <h4>10.3.1. The subtle attribute</h4>
- <p>
- The <dfn id="dfn-Crypto-attribute-subtle"><code>subtle</code></dfn> attribute provides
- an instance of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface which provides
- low-level cryptographic primitives and algorithms.
- </p>
- </div>
- </div>
- </div>
-
- <div id="algorithm-dictionary" class="section">
- <h2>11. Algorithm dictionary</h2>
- <p>
- The Algorithm object is a dictionary object [<cite><a href="#WebIDL">WEBIDL</a></cite>]
- which is used to specify an algorithm and any additional parameters required to fully
- specify the desired operation.
- </p>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-typedef (object or DOMString) <dfn id="dfn-AlgorithmIdentifier">AlgorithmIdentifier</dfn>;
-
-typedef <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> <dfn id="dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</dfn>;
-
-dictionary <dfn id="dfn-Algorithm">Algorithm</dfn> {
- required DOMString <a href="#dfn-Algorithm-name">name</a>;
-};
- </code></pre></div></div>
- <div id="algorithm-dictionary-members" class="section">
- <h3>11.1. <a href="#dfn-Algorithm">Algorithm</a> Dictionary Members</h3>
- <dl>
- <dt id="dfn-Algorithm-name">
- <code>name</code>
- </dt>
- <dd>
- The name of the <a href="#algorithms">registered algorithm</a> to use.
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="key-algorithm-dictionary" class="section">
- <h2>12. KeyAlgorithm dictionary</h2>
- <p>
- The KeyAlgorithm dictionary represents information about the contents of a given
- <a href="#dfn-CryptoKey">CryptoKey</a> object.
- </p>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-KeyAlgorithm">KeyAlgorithm</dfn> {
- required DOMString <a href="#dfn-KeyAlgorithm-name">name</a>
-};
- </code></pre></div></div>
- <div id="key-algorithm-dictionary-description" class="section">
- <h3>12.1. Description</h3>
- <p class="norm">This section is non-normative</p>
- <p>
- The <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> dictionary is provided to aid in
- documenting how fixed, public properties of a <a href="#dfn-CryptoKey">CryptoKey</a>
- are reflected back to an application. The actual dictionary type is never exposed
- to applications.
- </p>
- </div>
- <div id="key-algorithm-dictionary-members" class="section">
- <h3>12.2. KeyAlgorithm dictionary members</h3>
- <dl>
- <dt id="dfn-KeyAlgorithm-name">name</dt>
- <dd>
- The name of the algorithm used to generate the <a href="#dfn-CryptoKey">CryptoKey</a>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="cryptokey-interface" class="section">
- <h2>13. CryptoKey interface</h2>
- <p>
- The CryptoKey object represents an opaque reference to keying material that is managed by
- the user agent.
- </p>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-enum <a href="#dfn-KeyType">KeyType</a> { "public", "private", "secret" };
-
-enum <a href="#dfn-KeyUsage">KeyUsage</a> { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" };
-
-[Exposed=(Window,Worker)]
-interface <dfn id="dfn-CryptoKey">CryptoKey</dfn> {
- readonly attribute <a href="#dfn-KeyType">KeyType</a> <a href="#dfn-CryptoKey-type">type</a>;
- readonly attribute boolean <a href="#dfn-CryptoKey-extractable">extractable</a>;
- readonly attribute object <a href="#dfn-CryptoKey-algorithm">algorithm</a>;
- readonly attribute object <a href="#dfn-CryptoKey-usages">usages</a>;
-};
- </code></pre></div></div>
- <div id="cryptokey-interface-description" class="section">
- <h3>13.1. Description</h3>
- <p class="norm">This section is non-normative</p>
- <p>
- This specification provides a uniform interface for many different kinds of keying
- material managed by the user agent. This may include keys that have been generated by
- the user agent, derived from other keys by the user agent, imported to the user agent
- through user actions or using this API, pre-provisioned within software or hardware to
- which the user agent has access or made available to the user agent in other ways. The
- term key refers broadly to any keying material including actual keys for cryptographic
- operations and secret values obtained within key derivation or exchange operations.
- </p>
- <p>
- The CryptoKey object is not required to directly interface with the underlying key
- storage mechanism, and may instead simply be a reference for the user agent to
- understand how to obtain the keying material when needed, eg. when performing a
- cryptographic operation.
- </p>
- </div>
-
- <div id="cryptokey-interface-types" class="section">
- <h3>13.2. Key interface data types</h3>
- <dl>
- <dt id="dfn-KeyType"><code>KeyType</code></dt>
- <dd>
- The type of a key. The <dfn id="dfn-RecognizedKeyType">recognized key type values</dfn>
- are <code>"public"</code>, <code>"private"</code> and <code>"secret"</code>.
- Opaque keying material, including that used for symmetric algorithms, is represented by
- <code>"secret"</code>, while keys used as part of asymmetric algorithms composed of
- public/private keypairs will be either <code>"public"</code> or <code>"private"</code>.
- </dd>
- <dt id="dfn-KeyUsage"><code>KeyUsage</code></dt>
- <dd>
- A type of operation that may be performed using a key. The
- <dfn id="dfn-RecognizedKeyUsage">recognized key usage values</dfn> are
- <code>"encrypt"</code>,
- <code>"decrypt"</code>,
- <code>"sign"</code>,
- <code>"verify"</code>,
- <code>"deriveKey"</code>,
- <code>"deriveBits"</code>,
- <code>"wrapKey"</code> and
- <code>"unwrapKey"</code>.
- </dd>
- </dl>
- </div>
-
- <div id="cryptokey-interface-internal-slots" class="section">
- <h3>13.3. CryptoKey internal slots</h3>
- <p>
- Every <code>CryptoKey</code> object has a set of internal slots that store information
- about the key. These slots are not exposed as part of this specification; they
- represent internal state that an implementation uses to implement this specification.
- The notational convention used in [<a href="#ES262">ES262</a>] is re-used here; internal
- slots are identified by names enclosed in double square brackets [[ ]].
- </p>
- <p>
- All <code>CryptoKey</code> objects have internal slots named
- [[<dfn id="dfn-CryptoKey-slot-type">type</dfn>]],
- [[<dfn id="dfn-CryptoKey-slot-extractable">extractable</dfn>]],
- [[<dfn id="dfn-CryptoKey-slot-algorithm">algorithm</dfn>]],
- [[<dfn id="dfn-CryptoKey-slot-algorithm_cached">algorithm_cached</dfn>]],
- [[<dfn id="dfn-CryptoKey-slot-usages">usages</dfn>]],
- [[<dfn id="dfn-CryptoKey-slot-usages_cached">usages_cached</dfn>]], and
- [[<dfn id="dfn-CryptoKey-slot-handle">handle</dfn>]].
- </p>
- <p>
- The contents of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot shall be, or be derived from, a <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
- The contents of the [[<a href="#dfn-CryptoKey-slot-algorithm">usages</a>]] internal
- slot shall be of type Sequence<KeyUsage>.
- </p>
- <p class="note">
- The [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] slot is an opaque type that
- contains whatever data the underlying cryptographic implementation uses to represent a
- logical key. Different cryptographic implementations may use different types, ranging
- from opaque identifiers represented as integers, pointer types, or structures that
- provide identifying information. These handles are never exposed to applications.
- </p>
- </div>
-
- <div id="cryptokey-interface-members" class="section">
- <h3>13.4. CryptoKey interface members</h3>
- <dl>
- <dt id="dfn-CryptoKey-type"><code>type</code></dt>
- <dd>
- Reflects the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot,
- which contains the type of the underlying key.
- </dd>
- <dt id="dfn-CryptoKey-extractable"><code>extractable</code></dt>
- <dd>
- Reflects the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot, which indicates whether or not the raw keying material may be exported by the
- application.
- </dd>
- <dt id="dfn-CryptoKey-algorithm"><code>algorithm</code></dt>
- <dd>
- Returns the <a href="#concept-cached-object">cached ECMAScript object</a>
- associated with the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot.
- </dd>
- <dt id="dfn-CryptoKey-usages"><code>usages</code></dt>
- <dd>
- Returns the <a href="#concept-cached-object">cached ECMAScript object</a>
- associated with the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot,
- which indicates which cryptographic operations are permissible to be used with this key.
- </dd>
- </dl>
- </div>
-
- <div id="cryptokey-interface-clone" class="section">
- <h3>13.5. Structured clone algorithm</h3>
- <p>
- When a user agent is required to obtain a <a href="#structured-clone">structured clone</a>
- of a <a href="#dfn-CryptoKey">CryptoKey</a> object, it must run the following steps.
- </p>
- <ol>
- <li>
- Let <var>input</var> and <var>memory</var> be the corresponding inputs defined by the
- <a href="#structured-clone">internal structured cloning algorithm</a>, where
- <var>input</var> represents a <a href="#dfn-CryptoKey">CryptoKey</a> object to be
- cloned.
- </li>
- <li>
- Let <var>output</var> be a newly constructed <a href="#dfn-CryptoKey">CryptoKey</a>
- object.
- </li>
- <li>
- Let the [[<a href="#dfn-CryptoKey-slot-type">type</a>]], <a href="#dfn-CryptoKey-slot-extractable">[[extractable]]</a>, <a href="#dfn-CryptoKey-slot-algorithm">[[algorithm]]</a>, and <a href="#dfn-CryptoKey-slot-usages">[[usages]]</a> internal slots of <var>output</var>
- be set to the result of invoking the internal structured clone algorithm recursively
- on the corresponding internal slots of <var>input</var>, with the slot contents as the
- new "<var>input</var>" argument and <var>memory</var> as the new "<var>memory</var>"
- argument.
- </li>
- <li>
- Let the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>output</var> refer to the same cryptographic key data represented by the
- [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>input</var>.
- </li>
- </ol>
- <div class="note"><div class="noteHeader">Note</div>
- <strong>Implementation Note:</strong> When performing the structured clone algorithm in
- order to serialize a <code>CryptoKey</code> object, implementations must not allow the
- object to be deserialized as a different type. This is normatively required by the
- definition of structured clone, but it merits specific attention, as such
- deserialization may expose the contents of the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot, which in some
- implementations may contain cryptographic key data that should not be exposed to
- applications.
- </div>
- </div>
- </div>
-
- <div id="subtlecrypto-interface" class="section">
- <h2>14. SubtleCrypto interface</h2>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-enum <a href="#dfn-KeyFormat"><code>KeyFormat</code></a> { "raw", "spki", "pkcs8", "jwk" };
-
-[Exposed=(Window,Worker)]
-interface <dfn id="dfn-SubtleCrypto">SubtleCrypto</dfn> {
- Promise<any> <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> key,
- BufferSource data);
- Promise<any> <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> key,
- BufferSource data);
- Promise<any> <a href="#dfn-SubtleCrypto-method-sign">sign</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> key,
- BufferSource data);
- Promise<any> <a href="#dfn-SubtleCrypto-method-verify">verify</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> key,
- BufferSource signature,
- BufferSource data);
- Promise<any> <a href="#dfn-SubtleCrypto-method-digest">digest</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- BufferSource data);
-
- Promise<any> <a href="#dfn-SubtleCrypto-method-generateKey">generateKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- boolean extractable,
- sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
- Promise<any> <a href="#dfn-SubtleCrypto-method-deriveKey">deriveKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> baseKey,
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> derivedKeyType,
- boolean extractable,
- sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
- Promise<any> <a href="#dfn-SubtleCrypto-method-deriveBits">deriveBits</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- <a href="#dfn-CryptoKey">CryptoKey</a> baseKey,
- unsigned long length);
-
- <span class="comment">// TBD: <a href="https://www.w3.org/2012/webcrypto/track/issues/35">ISSUE-35</a></span>
- Promise<any> <a href="#dfn-SubtleCrypto-method-importKey">importKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
- (BufferSource or JsonWebKey) keyData,
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
- boolean extractable,
- sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
- Promise<any> <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format, <a href="#dfn-CryptoKey">CryptoKey</a> key);
-
- Promise<any> <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
- <a href="#dfn-CryptoKey">CryptoKey</a> key,
- <a href="#dfn-CryptoKey">CryptoKey</a> wrappingKey,
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> wrapAlgorithm);
- Promise<any> <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
- BufferSource wrappedKey,
- <a href="#dfn-CryptoKey">CryptoKey</a> unwrappingKey,
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> unwrapAlgorithm,
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> unwrappedKeyAlgorithm,
- boolean extractable,
- sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
-};
- </code></pre></div></div>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <ul>
- <li>
- <a href="https://www.w3.org/2012/webcrypto/track/issues/35">ISSUE-35</a>:
- The specification for wrapKey/unwrapKey does not specify how authors that do not trust
- the execution environment may indicate required attributes for keys that are
- unwrapped. An example is unwrapping a key with a non-extractable key, marking
- the newly unwrapped key as non extractable, and then further indicating that all
- keys unwrapped with the newly unwrapped key are also non-extractable.
- </li>
- </ul>
- </div>
- <div id="subtlecrypto-interface-description" class="section">
- <h3>14.1. Description</h3>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface provides a set of
- methods for dealing with low-level cryptographic primitives and algorithms. It is
- named <code>SubtleCrypto</code> to reflect the fact that many of these algorithms
- have subtle usage requirements in order to provide the required algorithmic
- security guarantees.
- </p>
- <p>
- For example, the direct use of an unauthenticated encryption scheme, such as
- <a href="#aes-ctr">AES in counter mode</a>, gives potential attackers the ability to
- manipulate bits in the output by manipulating bits in the input, compromising the
- integrity of the message. However, AES-CTR can be used securely in combination
- with other cryptographic primitives, such as message authentication codes, to ensure
- the integrity of the protected message, but only when the message authentication
- code is constructed over the encrypted message and IV.
- </p>
- <p>
- Developers making use of the SubtleCrypto interface are expected to be aware of the
- security concerns associated with both the design and implementation of the various
- algorithms provided. The raw algorithms are provided in order to allow developers
- maximum flexibility in implementing a variety of protocols and applications, each of
- which may represent the composition and security parameters in a unique manner that
- necessitate the use of the raw algorithms.
- </p>
- </div>
-
- <div id="subtlecrypto-interface-datatypes" class="section">
- <h3>14.2. Data Types</h3>
- <dl>
- <dt id="dfn-KeyFormat"><code>KeyFormat</code></dt>
- <dd>
- Specifies a serialization format for a key. The <dfn id="dfn-RecognizedKeyFormats">recognized key format values</dfn> are:
- <dl>
- <dt><code>"raw"</code></dt>
- <dd>An unformatted sequence of bytes. Intended for secret keys.</dd>
- <dt><code>"pkcs8"</code></dt>
- <dd>The DER encoding of the PrivateKeyInfo structure from <a href="#RFC5208">RFC 5208</a>.</dd>
- <dt><code>"spki"</code></dt>
- <dd>The DER encoding of the SubjectPublicKeyInfo structure from <a href="#RFC5280">RFC 5280</a>.</dd>
- <dt><code>"jwk"</code></dt>
- <dd>The key is a <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary encoded as a JavaScript object</dd>
- </dl>
- </dd>
- </dl>
- </div>
-
- <div id="subtlecrypto-interface-methods" class="section">
- <h3>14.3. Methods and Parameters</h3>
- <div class="note"><div class="noteHeader">Note</div>
- <p>
- All errors are reported asynchronously by rejecting the returned
- Promise. This includes Web IDL type mapping errors.
- </p>
- </div>
- <div id="SubtleCrypto-method-encrypt" class="section">
- <h4>14.3.1. The encrypt method</h4>
- <p>
- The <dfn id="dfn-SubtleCrypto-method-encrypt"><code>encrypt</code></dfn>
- method returns a new Promise object that will encrypt data using
- the specified
- <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
- the supplied <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act
- as follows:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var> and <var>key</var> be the
- <code>algorithm</code> and <code>key</code> parameters
- passed to the <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"encrypt"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> does not contain an entry that is <code>"encrypt"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be the result of performing the encrypt
- operation specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>
- and <var>key</var> and with <var>data</var> as <var>plaintext</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with <var>ciphertext</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-decrypt" class="section">
- <h4>14.3.2. The decrypt method</h4>
- <p>
- The <dfn id="dfn-SubtleCrypto-method-decrypt"><code>decrypt</code></dfn>
- method returns a new Promise object that will decrypt data using the specified
- <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
- the supplied <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act
- as follows:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var> and <var>key</var> be the
- <code>algorithm</code> and <code>key</code>parameters
- passed to the <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"decrypt"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> does not contain an entry that is <code>"decrypt"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>plaintext</var> be the result of performing the decrypt
- operation specified by <var>normalizedAlgorithm</var> using <var>key</var>
- and <var>algorithm</var>
- and with <var>data</var> as <var>ciphertext</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-sign" class="section">
- <h4>14.3.3. The sign method</h4>
- <p>
- The <dfn id="dfn-SubtleCrypto-method-sign"><code>sign</code></dfn> method returns a
- new Promise object that will sign data using the specified <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with the supplied
- <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act as follows:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var> and <var>key</var> be the
- <code>algorithm</code> and <code>key</code> parameters
- passed to the <a href="#dfn-SubtleCrypto-method-sign">sign</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-sign">sign</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"sign"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> does not contain an entry that is <code>"sign"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the sign operation
- specified by <var>normalizedAlgorithm</var> using <var>key</var> and
- <var>algorithm</var> and with <var>data</var> as <var>message</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-verify" class="section">
- <h4>14.3.4. The verify method</h4>
- <p>
- The <dfn id="dfn-SubtleCrypto-method-verify"><code>verify</code></dfn> method returns
- a new Promise object that will verify data using the specified <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with the supplied
- <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act as follows:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var> and <var>key</var>
- be the <code>algorithm</code> and <code>key</code> parameters passed to the
- <a href="#dfn-SubtleCrypto-method-verify">verify</a> method, respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>signature</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>signature</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-verify">verify</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"verify"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-verify">verify</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> does not contain an entry that is <code>"verify"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the verify operation
- specified by <var>normalizedAlgorithm</var> using <var>key</var>,
- <var>algorithm</var> and
- <var>signature</var> and with <var>data</var> as <var>message</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-digest" class="section">
- <h4>14.3.5. The digest method</h4>
- <p>
- The <dfn id="dfn-SubtleCrypto-method-digest"><code>digest</code></dfn> method returns
- a new Promise object that will digest data using the specified
- <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a>.
- It must act as follows:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var> be the <code>algorithm</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-digest">digest</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
- cloning the data</a> of the <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-digest">digest</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"digest"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the digest
- operation specified by <var>normalizedAlgorithm</var> using
- <var>algorithm</var>, with <var>data</var>
- as <var>message</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-generateKey" class="section">
- <h4>14.3.6. The generateKey method</h4>
- <p>
- When invoked, <dfn id="dfn-SubtleCrypto-method-generateKey">
- <code>generateKey</code></dfn> <span class="RFC2119">MUST</span> perform the
- following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var>, <var>extractable</var> and <var>usages</var>
- be the <code>algorithm</code>, <code>extractable</code> and <code>keyUsages</code>
- parameters passed to the
- <a href="#dfn-SubtleCrypto-method-generateKey">generateKey</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"generateKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of executing the generate key operation
- specified by <var>normalizedAlgorithm</var> using
- <var>algorithm</var>, <var>extractable</var> and <var>usages</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>result</var> is a <a href="#dfn-CryptoKey">CryptoKey</a> object:</dt>
- <dd>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
- <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
- </p>
- </dd>
- <dt>If <var>result</var> is a <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a> object:</dt>
- <dd>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of the
- <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute of
- <var>result</var> is the empty sequence, then
- <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-deriveKey" class="section">
- <h4>14.3.7. The deriveKey method</h4>
- <p>
- When invoked, <dfn id="dfn-SubtleCrypto-method-deriveKey"><code>deriveKey</code></dfn>
- <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var>, <var>baseKey</var>, <var>derivedKeyType</var>,
- <var>extractable</var> and <var>usages</var> be the <code>algorithm</code>,
- <code>baseKey</code>, <code>derivedKeyType</code>, <code>extractable</code> and
- <code>keyUsages</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-deriveKey">deriveKey</a> method, respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"deriveBits"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedDerivedKeyAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>derivedKeyType</var> and <code>op</code> set to
- <code>"importKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> does not identify a <a href="#algorithms">registered algorithm</a> that supports the derive bits
- operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> does not identify a
- <a href="#algorithms">registered algorithm</a> that supports the get key length
- operation, then <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>baseKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>baseKey</var> does not contain an entry that is <code>"deriveKey"</code>,
- then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>length</var> be the result of executing the get key length
- algorithm specified by <var>normalizedDerivedKeyAlgorithm</var> using
- <var>derivedKeyType</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>secret</var> be the result of executing the derive bits operation
- specified by <var>normalizedAlgorithm</var> using
- <var>key</var>, <var>algorithm</var> and <var>length</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of executing the import key operation
- specified by <var>normalizedDerivedKeyAlgorithm</var> using <code>"raw"</code> as
- <var>format</var>, <var>secret</var> as <var>keyData</var>,
- <var>derivedKeyType</var> as <var>algorithm</var> and using
- <var>extractable</var> and <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
- <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-deriveBits" class="section">
- <h4>14.3.8. The deriveBits method</h4>
- <p>
- When invoked, <dfn id="dfn-SubtleCrypto-method-deriveBits"><code>deriveBits</code></dfn>
- <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>algorithm</var>, <var>baseKey</var> and <var>length</var>,
- be the <code>algorithm</code>,
- <code>baseKey</code> and <code>length</code>
- parameters passed to the
- <a href="#dfn-SubtleCrypto-method-deriveBits">deriveBits</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"deriveBits"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise object.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>baseKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>baseKey</var> does not contain an entry that is <code>"deriveBits"</code>,
- then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-ArrayBuffer">ArrayBuffer</a>
- containing the result of executing the derive bits operation
- specified by <var>normalizedAlgorithm</var> using <var>baseKey</var>,
- <var>algorithm</var> and <var>length</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-importKey" class="section">
- <h4>14.3.9. The <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method</h4>
- <p>
- When invoked, the <dfn id="dfn-SubtleCrypto-method-importKey"><code>importKey</code></dfn> method <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>format</var>, <var>algorithm</var>, <var>extractable</var> and
- <var>usages</var>, be the <code>format</code>, <code>algorithm</code>,
- <code>extractable</code> and <code>keyUsages</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method, respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"importKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is equal to the string <code>"raw"</code>,
- <code>"pkcs8"</code>, or <code>"spki"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <code>keyData</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method is a
- JsonWebKey dictionary, <a href="#concept-throw">throw</a> a
- <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>keyData</var> be the result of
- <a href="#concept-clone-BufferSource">cloning the data</a> of the
- <code>keyData</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is equal to the string <code>"jwk"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <code>keyData</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method is not a
- JsonWebKey dictionary, <a href="#concept-throw">throw</a> a
- <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>keyData</var> be the <code>keyData</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> object that
- results from performing the import key operation specified by
- <var>normalizedAlgorithm</var> using <var>keyData</var>,
- <var>algorithm</var>,
- <var>format</var>, <var>extractable</var> and <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
- <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>result</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal
- slot of <var>result</var> to the <a href="#concept-normalized-usages">normalized
- value</a> of <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- <div class="note"><div class="noteHeader">Note</div>
- <p class="norm">
- This note is non-normative.
- </p>
- <p>
- For structured key formats, <code>"spki"</code>, <code>"pks8"</code>
- and <code>"jwk"</code>, fields that are not explicitly referred to in the key
- import procedures for an algorithm are ignored.
- </p>
- </div>
- </div>
-
- <div id="SubtleCrypto-method-exportKey" class="section">
- <h4>14.3.10. The <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> method</h4>
- <p>
- When invoked, the <dfn id="dfn-SubtleCrypto-method-exportKey"><code>exportKey</code></dfn> method <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>format</var> and <var>key</var> be the <code>format</code> and
- <code>key</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> method, respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> does not identify a <a href="#algorithms">registered algorithm</a>
- that supports the export key operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var> is false, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the export key operation
- specified by the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> using <var>key</var> and <var>format</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-wrapKey" class="section">
- <h4>14.3.11. The wrapKey method</h4>
- <p>
- When invoked, the <dfn id="dfn-SubtleCrypto-method-wrapKey">wrapKey</dfn> method <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>format</var>, <var>key</var>, <var>wrappingKey</var> and
- <var>algorithm</var> be the <code>format</code>, <code>key</code>,
- <code>wrappingKey</code> and <code>wrapAlgorithm</code> parameters passed to the
- <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"wrapKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"encrypt"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> does not identify a
- <a href="#algorithms">registered algorithm</a> that supports the encrypt or wrap
- key operation, then <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>wrappingKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>wrappingKey</var> does not contain an entry that is <code>"wrapKey"</code>,
- then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the algorithm identified by the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> does not support the export key operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var> is false, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be the result of performing the export key operation specified
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> using <var>key</var> and <var>format</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is equal to the strings <code>"raw"</code>,
- <code>"pkcs8"</code>, or <code>"spki"</code>:
- </dt>
- <dd>
- Set <var>bytes</var> be set to <var>key</var>.
- </dd>
- <dt>
- If <var>format</var> is equal to the string <code>"jwk"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Convert <var>key</var> to an ECMAScript Object, as specified in [
- <a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- <li>
- <p>
- Let <var>json</var> be the result of representing <var>key</var> as a
- UTF-16 string conforming to the JSON grammar; for example, by executing
- the <code>JSON.stringify</code> algorithm specified in
- <a href="#ECMA-262">ECMA262</a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>bytes</var> be the byte sequence the results from converting
- <var>json</var>, a JavaScript String comprised of UTF-16 code points, to
- UTF-8 code points.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- <div class="note"><div class="noteHeader">Note</div>
- <p class="norm">
- This note is non-normative.
- </p>
- <p>
- The key wrapping operations for some algorithms place constraints on the payload
- size. For example AES-KW requires the payload to be a multiple of 8 bytes in
- length and RSA-OAEP places a restriction on the length. For key formats that
- offer flexibility in serialization of a given key (for example JWK),
- implementations may choose to adapt the serialization to the constraints of
- the wrapping algorithm. This is why JSON.stringify is not normatively required,
- as otherwise it would prohibit implementations from introducing added
- padding.
- </p>
- </div>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>normalizedAlgorithm</var> supports the wrap key operation:</dt>
- <dd>
- <p>
- Let <var>result</var> be the result of performing the wrap key operation
- specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
- <var>wrappingKey</var> as <var>key</var> and <var>bytes</var> as
- <var>plaintext</var>.
- </p>
- </dd>
- <dt>Otherwise, if <var>normalizedAlgorithm</var> supports the encrypt operation:</dt>
- <dd>
- <p>
- Let <var>result</var> be the result of performing the encrypt operation
- specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
- <var>wrappingKey</var> as <var>key</var> and <var>bytes</var> as
- <var>plaintext</var>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="SubtleCrypto-method-unwrapKey" class="section">
- <h4>14.3.12. The unwrapKey method</h4>
- <p>
- When invoked, the <dfn id="dfn-SubtleCrypto-method-unwrapKey">unwrapKey</dfn> method
- <span class="RFC2119">MUST</span> perform the following steps:
- </p>
- <ol>
- <li>
- <p>
- Let <var>format</var>, <var>unwrappingKey</var>,
- <var>algorithm</var>, <var>unwrappedKeyAlgorithm</var>,
- <var>extractable</var> and <var>usages</var>,
- be the <code>format</code>, <code>unwrappingKey</code>,
- <code>unwrapAlgorithm</code>, <code>unwrappedKeyAlgorithm</code>,
- <code>extractable</code> and <code>keyUsages</code>
- parameters passed to the
- <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a> method,
- respectively.
- </p>
- </li>
- <li>
- <p>
- Let <var>wrappedKey</var> be the result of
- <a href="#concept-clone-BufferSource">cloning the data</a> of the
- <code>data</code> parameter passed to the
- <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a> method.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"unwrapKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, let <var>normalizedAlgorithm</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
- <code>"decrypt"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>normalizedKeyAlgorithm</var> be the result of <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
- <code>alg</code> set to <var>unwrappedKeyAlgorithm</var> and <code>op</code> set
- to <code>"importKey"</code>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred, return a Promise rejected with
- <var>normalizedKeyAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>promise</var> be a new Promise.
- </p>
- </li>
- <li>
- <p>
- Return <var>promise</var> and asynchronously perform the remaining steps.
- </p>
- </li>
- <li>
- <p>
- If the following steps or referenced procedures say to
- <a href="#concept-throw">throw</a> an error,
- reject <var>promise</var> with
- the returned error and then
- <a href="#terminate-the-algorithm">terminate the algorithm.</a>
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is not equal to the
- <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>unwrappingKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>unwrappingKey</var> does not contain an entry that is
- <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>normalizedAlgorithm</var> supports an unwrap key operation:</dt>
- <dd>
- Let <var>key</var> be the result of performing the unwrap key operation
- specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
- <var>unwrappingKey</var> as <var>key</var> and <var>wrappedKey</var> as
- <var>ciphertext</var>.
- </dd>
- <dt>
- Otherwise, if <var>normalizedAlgorithm</var> supports a decrypt
- operation:
- </dt>
- <dd>
- Let <var>key</var> be the result of performing the decrypt operation specified
- by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
- <var>unwrappingKey</var> as <var>key</var> and <var>wrappedKey</var> as
- <var>ciphertext</var>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is equal to the strings <code>"raw"</code>,
- <code>"pkcs8"</code>, or <code>"spki"</code>:
- </dt>
- <dd>
- Set <var>bytes</var> be set to <var>key</var>.
- </dd>
- <dt>
- If <var>format</var> is equal to the string <code>"jwk"</code>:
- </dt>
- <dd>
- Let <var>bytes</var> be the result of executing the
- <a href="#concept-parse-a-jwk">parse a JWK</a> algorithm, withe <var>key</var>
- as the <code>data</code> to be parsed.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the import key operation
- specified by <var>normalizedKeyAlgorithm</var> using
- <var>unwrappedKeyAlgorithm</var> as <var>algorithm</var>, <var>format</var>,
- <var>usages</var>
- and <var>extractable</var> and with
- <var>bytes</var> as <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
- <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>result</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal
- slot of <var>result</var> to the <a href="#concept-normalized-usages">normalized
- value</a> of <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Resolve <var>promise</var> with
- <var>result</var>.
- </p>
- </li>
- </ol>
- </div>
- </div>
- <div id="SubtleCrypto-Exceptions" class="section">
- <h3>14.4. Exceptions</h3>
- <p>
- The methods of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface return errors
- by rejecting the returned promise with a
- <a href="#dfn-DOMException">DOMException</a>. The following DOMException types from
- [<a href="#DOM4">DOM4</a>] are used:
- </p>
- <table>
- <tbody>
- <tr>
- <th>Type</th>
- <th>Message (optional)</th>
- </tr>
- <tr>
- <td><dfn id="dfn-NotSupportedError"><code>NotSupportedError</code></dfn></td>
- <td>The algorithm is not supported</td>
- </tr>
- <tr>
- <td><dfn id="dfn-SyntaxError"><code>SyntaxError</code></dfn></td>
- <td>A required parameter was missing or out-of-range</td>
- </tr>
- <tr>
- <td><dfn id="dfn-InvalidStateError"><code>InvalidStateError</code></dfn></td>
- <td>The requested operation is not valid for the current state of the provided key.</td>
- </tr>
- <tr>
- <td><dfn id="dfn-InvalidAccessError"><code>InvalidAccessError</code></dfn></td>
- <td>The requested operation is not valid for the provided key</td>
- </tr>
- <tr>
- <td><dfn id="dfn-UnknownError"><code>UnknownError</code></dfn></td>
- <td>The operation failed for an unknown transient reason (e.g. out of memory)</td>
- </tr>
- <tr>
- <td><dfn id="dfn-DataError"><code>DataError</code></dfn></td>
- <td>Data provided to an operation does not meet requirements</td>
- </tr>
- <tr>
- <td><dfn id="dfn-OperationError"><code>OperationError</code></dfn></td>
- <td>The operation failed for an operation-specific reason</td>
- </tr>
- </tbody>
- </table>
- <p>
- When this specification says to
- <dfn id="concept-throw">throw</dfn> an error, the user agent must
- <a href="http://heycam.github.io/webidl/#dfn-throw">throw</a> an error as described in
- [<a href="#WebIDL">WEBIDL</a>]. When this occurs in a sub-algorithm,
- this results in termination of execution of the sub-algorithm and all ancestor algorithms
- until one is reached that explicitly describes procedures for catching exceptions.
- </p>
- </div>
- </div>
-
- <div id="JsonWebKey-dictionary" class="section">
- <h2>15. JsonWebKey dictionary</h2>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaOtherPrimesInfo">RsaOtherPrimesInfo</dfn> {
- <span class="comment">// The following fields are defined in Section 6.3.2.7 of <a href="#jwa">JSON Web Algorithms</a></span>
- DOMString r;
- DOMString d;
- DOMString t;
-};
-
-dictionary <dfn id="dfn-JsonWebKey">JsonWebKey</dfn> {
- <span class="comment">// The following fields are defined in Section 3.1 of <a href="#jwk">JSON Web Key</a></span>
- DOMString kty;
- DOMString use;
- sequence<DOMString> key_ops;
- DOMString alg;
-
- <span class="comment">// The following fields are defined in <a href="#iana-section-jwk">JSON Web Key Parameters Registration</a></span>
- boolean ext;
-
- <span class="comment">// The following fields are defined in Section 6 of <a href="#jwa">JSON Web Algorithms</a></span>
- 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;
-};
- </code></pre></div></div>
- <div id="JsonWebKey-description">
- <h3>Description</h3>
- <p class="norm">The following section is non-normative</p>
- <p>
- The <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary provides a way to represent
- and exchange cryptographic keys represented by the <a href="#jwk">JSON Web Key</a>
- structure, while allowing native and efficient use within Web Cryptography API
- applications.
- </p>
- </div>
- </div>
-
- <div id="big-integer" class="section">
- <h2>16. BigInteger</h2>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-typedef Uint8Array <dfn id="dfn-BigInteger">BigInteger</dfn>;
- </code></pre></div></div>
- <p>
- The <a href="#dfn-BigInteger">BigInteger</a> typedef is a <code>Uint8Array</code> that
- holds an arbitrary magnitude unsigned integer in big-endian order. Values read from
- the API SHALL have minimal typed array length (that is, at most 7 leading zero bits,
- except the value 0 which shall have length 8 bits). The API SHALL accept values with
- any number of leading zero bits, including the empty array, which represents zero.
- </p>
-
- <div class="note"><div class="noteHeader">Note</div>
- <strong>Implementation Note:</strong> Since the integer is unsigned, the highest order bit
- is NOT a sign bit. Implementors should take care when mapping to big integer
- implementations that expected signed integers.
- </div>
- </div>
-
- <div id="keypair" class="section">
- <h2>17. CryptoKeyPair dictionary</h2>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-CryptoKeyPair">CryptoKeyPair</dfn> {
- <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-CryptoKey-publicKey">publicKey</dfn>;
- <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-CryptoKey-privateKey">privateKey</dfn>;
-};
- </code></pre></div></div>
- <p>
- The <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a> dictionary represents an
- asymmetric key pair that is comprised of both public and private keys.
- </p>
- </div>
-
- <div id="algorithms" class="section">
- <h2>18. Algorithms</h2>
- <div id="algorithm-overview" class="section">
- <h3>18.1. Overview</h3>
- <p class="norm">This section is non-normative.</p>
- <p>
- In addition to providing a common interface to perform cryptographic operations, by
- way of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface, this specification
- also provides descriptions for a variety of algorithms that authors may wish to use and
- that User Agents may choose to implement. This includes a selection of commonly-deployed
- symmetric and asymmetric algorithms, key derivation mechanisms, and methods for wrapping
- and unwrapping keys. Further, this specification defines a process to allow additional
- specifications to introduce additional cryptographic algorithms.
- </p>
- </div>
-
- <div id="algorithm-concepts" class="section">
- <h3>18.2. Concepts</h3>
- <div id="algorithm-concepts-naming" class="section">
- <h4>18.2.1. Naming</h4>
- <p>
- Every cryptographic algorithm defined for use with the Web Cryptography API
- <span class="RFC2119">MUST</span> have a unique name, referred to as its
- <dfn id="recognized-algorithm-name">recognized algorithm name</dfn>, such that no
- other specification defines the same case-sensitive string for use with the
- Web Cryptography API.
- </p>
- </div>
- <div id="algorithm-concepts-operations" class="section">
- <h4>18.2.2. Supported Operations</h4>
- <p>
- Every cryptographic algorithm defined for use with the Web Cryptography API has a list
- of <dfn id="supported-operation">supported operations</dfn>, which are a set of
- sub-algorithms to be invoked by the <a href="#dfn-SubtleCrypto">SubtleCrypto</a>
- interface in order to perform the desired cryptographic operation. This specification
- makes use of the following operations:
- </p>
- <ul>
- <li>encrypt</li>
- <li>decrypt</li>
- <li>sign</li>
- <li>verify</li>
- <li>deriveBits</li>
- <li>wrapKey</li>
- <li>unwrapKey</li>
- <li>generateKey</li>
- <li>importKey</li>
- <li>exportKey</li>
- <li>getLength</li>
- </ul>
- <p>
- If a given algorithm specification does not list a particular operation as supported,
- or explicitly lists an operation as not-supported, then the User Agent
- <span class="RFC2119">MUST</span> behave as if the invocation of the sub-algorithm
- threw a NotSupportedError.
- </p>
- </div>
- <div id="algorithm-concepts-normalization" class="section">
- <h4>18.2.3. Normalization</h4>
- <p>
- Every cryptographic algorithm defined for use with the Web Cryptography API <span class="RFC2119">MUST</span> define, for every <a href="#supported-operation">
- supported operation</a>, the IDL type to use for <a href="#concept-algorithm-normalization">algorithm normalization</a>, as well as the
- IDL type or types of the return values of the sub-algorithms.
- </p>
- </div>
- </div>
-
- <div id="algorithm-conventions" class="section">
- <h3>18.3. Specification Conventions</h3>
- <p>
- Every cryptographic algorithm definition within this specification employs the following
- specification conventions. A section, titled <em>"Registration"</em>, will include the
- <a href="#recognized-algorithm-name">recognized algorithm name</a>. Additionally, it
- includes a table, which will list each of the <a href="#supported-operation">supported
- operations</a> as rows, identified by the <em>Operation</em> column. The contents of the
- <em>Parameters</em> column for a given row will contain the IDL type to use for <a href="#concept-algorithm-normalization">algorithm normalization</a> for that operation,
- and the contents of the <em>Result</em> column for that row indicate the IDL type that
- results from performing the supported operation.
- </p>
- <p>
- If a conforming User Agent implements an algorithm, it
- <span class="RFC2119">MUST</span> implement all of the <a href="#supported-operation">
- supported operations</a> and <span class="RFC2119">MUST</span> return the IDL type
- specified.
- </p>
- <p>
- Additionally, upon initialization, conforming User Agents must perform the
- <a href="#concept-define-an-algorithm">define an algorithm</a> steps for each of
- the supported operations, registering their IDL parameter type as indicated.
- </p>
- </div>
-
- <div id="algorithm-normalizing" class="section">
- <h3>18.4. Algorithm Normalization</h3>
- <div id="algorithm-normalizing-description" class="section">
- <h4>18.4.1. Description</h4>
- <p class="norm">This section is non-normative</p>
- <p>
- The <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> typedef permits
- algorithms to either be specified as a <a href="#dfn-DOMString">DOMString</a> or an
- object. The usage of <a href="#dfn-DOMString">DOMString</a> is to permit authors a
- short-hand for noting algorithms that have no parameters (e.g. SHA-1).
- The usage of object is to allow an <a href="#dfn-Algorithm">Algorithm</a> (or appropriate subclass) to be specified, which
- contains all of the associated parameters for an object.
- </p>
- <p>
- Because of this, it's necessary to define the algorithm for converting an <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> into an appropriate dictionary
- that is usable with this API. This algorithm must be extensible, so as to allow new
- cryptographic algorithms to be added, and consistent, so that Web IDL type mapping can
- occur before any control is returned to the calling script, which would potentially
- allow the mutation of parameters or the script environment.
- </p>
- </div>
-
- <div id="algorithm-normalizing-internal" class="section">
- <h4>18.4.2. Internal State Objects</h4>
- <p>
- This specification makes use of an internal object,
- [[<dfn id="dfn-supportedAlgorithms">supportedAlgorithms</dfn>]]. This internal object is
- not exposed to applications.
- </p>
- <p>
- Because this value is not exposed to applications, the exact type is not specified.
- It is only required to behave as an associative container of key/value pairs, where
- comparisons of keys are performed in a case-sensitive manner.
- </p>
- <p>
- The initial contents of this internal object are as follows:
- </p>
- <ol>
- <li>
- <p>
- For each value, <var>v</var> in the List of <a href="#supported-operation">supported operations</a>, set the <var>v</var> key of
- the internal object [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]]
- to a new associative container.
- </p>
- </li>
- </ol>
- </div>
-
- <div id="algorithm-normalizing-define-an-algorithm" class="section">
- <h4>18.4.3. Defining an Algorithm</h4>
- <p>
- The <dfn id="concept-define-an-algorithm">define an algorithm</dfn> algorithm is used
- by specification authors to indicate how a user agent should normalize arguments for a
- particular algorithm. Its input is an algorithm name <var>alg</var>, represented as a
- DOMString, operation name <var>op</var>, represented as a DOMString, and desired IDL
- dictionary type <var>type</var>. The algorithm behaves as follows:
- </p>
- <ol>
- <li>
- Let <var>registeredAlgorithms</var> be the associative container stored at the
- <var>op</var> key of [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]]..
- </li>
- <li>
- Set the <var>alg</var> key of <var>registeredAlgorithms</var> to the IDL dictionary
- type <var>type</var>.
- </li>
- </ol>
- </div>
-
- <div id="algorithm-normalizing-normalize-an-algorithm" class="section">
- <h4>18.4.4. Normalizing an algorithm</h4>
- <p>
- The <dfn id="dfn-normalize-an-algorithm">normalize an algorithm</dfn> algorithm defines
- a process for coercing inputs to a targeted IDL dictionary type, after Web IDL
- conversion has occurred. It is designed to be extensible, to allow future specifications
- to define additional algorithms, as well as safe for use with Promises. Its input is an
- operation name <var>op</var> and an <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> <var>alg</var>. Its output is
- either an IDL dictionary type or an error. It behaves as follows:
- </p>
- <dl class="switch">
- <dt>If <var>alg</var> is an instance of a DOMString:</dt>
- <dd>
- <p>
- Return the result of running the <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a> algorithm, with
- the <code>alg</code> set to a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
- dictionary whose <a href="#dfn-KeyAlgorithm-name">name</a> attribute is
- <var>alg</var>, and with the <code>op</code> set to <var>op</var>.
- </p>
- </dd>
- <dt>If <var>alg</var> is an object:</dt>
- <dd>
- <ol>
- <li>
- Let <var>registeredAlgorithms</var> be the associative container stored at the
- <code>op</code> key of [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]].
- </li>
- <li>
- Let <var>initialAlg</var> be the result of converting the ECMAScript object
- represented by <var>alg</var> to the IDL dictionary type <a href="#dfn-Algorithm">Algorithm</a>, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </li>
- <li>
- If an error occurred, return the error and terminate this algorithm.
- </li>
- <li>
- Let <var>algName</var> be the value of the <a href="#dfn-Algorithm-name">name</a>
- attribute of <var>initialAlg</var>.
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>registeredAlgorithms</var> contains a key that is a
- <a href="#case-insensitive">case-insensitive</a> string match for
- <var>algName</var>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Set <var>algName</var> to the value of the matching key.
- </p>
- </li>
- <li>
- <p>
- Let <var>desiredType</var> be the IDL dictionary type stored at
- <var>algName</var> in <var>registeredAlgorithms</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- Return a new <code>NotSupportedError</code> and terminate this algorithm.
- </dd>
- </dl>
- </li>
- <li>
- Let <var>normalizedAlgorithm</var> be the result of converting the ECMAScript
- object represented by <var>alg</var> to the IDL dictionary type
- <var>desiredType</var>, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </li>
- <li>
- Set the <a href="#dfn-Algorithm-name">name</a> attribute of
- <var>normalizedAlgorithm</var> to <var>algName</var>.
- </li>
- <li>
- If an error occurred, return the error and terminate this algorithm.
- </li>
- <li>
- Let <var>dictionaries</var> be a list consisting of the IDL dictionary type
- <var>desiredType</var> and all of <var>desiredType</var>'s inherited dictionaries,
- in order from least to most derived.
- </li>
- <li>
- <p>
- For each dictionary <var>dictionary</var> in <var>dictionaries</var>:
- </p>
- <ol>
- <li>
- <p>
- For each dictionary member <var>member</var> declared on
- <var>dictionary</var>, in order:
- </p>
- <ol>
- <li>
- Let <var>key</var> be the identifier of <var>member</var>.
- </li>
- <li>
- Let <var>idlValue</var> be the value of the dictionary member with
- key name of <var>key</var> on <var>normalizedAlgorithm</var>.
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>member</var> is of the type
- <a href="http://heycam.github.io/webidl/#common-BufferSource">BufferSource</a> and is
- present:
- </dt>
- <dd>
- Set the dictionary member on <var>normalizedAlgorithm</var> with key
- name <var>key</var> to a <a href="#concept-clone-BufferSource">clone of
- <var>idlValue</var></a>, replacing the current value.
- </dd>
- <dt>
- If <var>member</var> is of the type
- <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a>:
- </dt>
- <dd>
- Set the dictionary member on <var>normalizedAlgorithm</var> with key
- name <var>key</var> to the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>,
- with the <code>alg</code> set to <var>idlValue</var> and the
- <code>op</code> set to <code>"digest"</code>.
- </dd>
- <dt>
- If <var>member</var> is of the type
- <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a>:
- </dt>
- <dd>
- Set the dictionary member on <var>normalizedAlgorithm</var> with key
- name <var>key</var> to the result of
- <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>,
- with the <code>alg</code> set to <var>idlValue</var> and the
- <code>op</code> set to the operation defined by the specification
- that definines the algorithm identified by <var>algName</var>.
- </dd>
- </dl>
- </li>
- <li>
- If an error occurred, return the error and terminate this algorithm.
- </li>
- </ol>
- </li>
- </ol>
- </li>
- <li>
- Return <var>normalizedAlgorithm</var>.
- </li>
- </ol>
- </dd>
- </dl>
- </div>
-
- </div>
-
- <div id="algorithm-recommendations" class="section">
- <h3>18.5. Recommendations</h3>
- <p class="norm">This section is non-normative.</p>
- <div id="algorithm-recommendations-authors" class="section">
- <h4>18.5.1. For Authors</h4>
- <p>
- As this API is meant to be extensible, in order to keep up with future developments
- within cryptography, there are no algorithms that conforming user agents are required
- to implement. As such, authors should check to see what algorithms are currently
- recommended and supported by implementations.
- </p>
- <p>
- As highlighted in the <a href="#security-considerations">Security Considerations</a>,
- even cryptographic algorithms that might be considered strong for one purpose may be
- insufficient when used with another purpose. Authors should therefore proceed with
- extreme caution before inventing new cryptographic protocols.
- </p>
- <p>
- Additionally, this specification includes several algorithms which, in their default
- usage, can result in cryptographic vulnerabilities. While these concerns may be
- mitigated, such as through the combination and composition with additional algorithms
- provided by this specification, authors should proceed with caution and review the
- relevant cryptographic literature before using a given algorithm. The inclusion of
- algorithms within this specification is not an indicator of their suitability for any
- or all purpose, and instead merely serve to provide as a specification for how a
- conforming User Agent must implement the given algorithm, if it choses to implement
- the algorithm.
- </p>
- </div>
- <div id="algorithm-recommendations-implementers" class="section">
- <h4>18.5.2. For Implementers</h4>
- <p>
- In order to promote interoperability for developers, this specification includes a
- list of suggested algorithms. These are considered to be the most widely used
- algorithms in practice at the time of writing, and therefore provide a good starting
- point for initial implementations of this specification. The suggested algorithms are:
- </p>
- <ul>
- <li>
- <a href="#hmac">HMAC</a> using <a href="#alg-sha-1">SHA-1</a>
- </li>
- <li>
- <a href="#hmac">HMAC</a> using <a href="#alg-sha-256">SHA-256</a>
- </li>
- <li>
- <a href="#rsassa-pkcs1">RSASSA-PKCS1-v1_5</a> using
- <a href="#alg-sha-256">SHA-1</a>
- </li>
- <li>
- <a href="#rsa-pss">RSA-PSS</a> using <a href="#alg-sha-256">SHA-256</a>
- and MGF1 with <a href="#alg-sha-256">SHA-256</a>.
- </li>
- <li>
- <a href="#rsa-oaep">RSA-OAEP</a> using <a href="#alg-sha-256">SHA-256</a>
- and MGF1 with <a href="#alg-sha-256">SHA-256</a>.
- </li>
- <li>
- <a href="#ecdsa">ECDSA</a> using <a href="#dfn-NamedCurve-p256">P-256</a>
- curve and <a href="#alg-sha-256">SHA-256</a>
- </li>
- <li><a href="#aes-cbc">AES-CBC</a></li>
- </ul>
- </div>
- </div>
- </div>
-
- <div id="algorithm-overview" class="section">
- <h2>19. Algorithm Overview</h2>
- <p class="norm">The following section is non-normative.</p>
- <p>
- The table below contains an overview of the algorithms described within this
- specification, as well as the set of <a href="#subtlecrypto-interface-methods">subtlecrypto
- methods</a> the algorithm may be used with. In order for
- an algorithm to be used with a method the corresponding
- operation or operations, as defined
- in the procedures for the method, must be defined in the algorithm specification.
- Note that this mapping of methods to underlying
- operations is not one-to-one:
- <ul>
- <li>
- <p>The <a href="#SubtleCrypto-method-encrypt">encrypt</a> method requires the encrypt operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-decrypt">decrypt</a> method requires the decrypt operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-sign">sign</a> method requires the sign operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-verify">decrypt</a> method requires the verify operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-generateKey">generateKey</a> method requires the generateKey operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-deriveKey">deriveKey</a> method requires the
- deriveBits operation for the key derivation algorithm and the get length and importKey operations
- for the derived key algorithm.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-digest">digest</a> method requires the digest operation.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-wrapKey">wrapKey</a> method requires the either
- the encrypt or wrapKey operation for the wrapping algorithm and the exportKey operation
- for the wrapped key algorithm.</p>
- </li>
- <li>
- <p>The <a href="#SubtleCrypto-method-unwrapKey">unwrapKey</a> method requires the either
- the decrypt or unwrapKey operation for the unwrapping algorithm and the importKey operation
- for the unwrapped key algorithm.</p>
- </li>
- </ul>
- </p>
- <p class="note">
- Application developers and script authors should not interpret this table as a
- recommendation for the use of particular algorithms. Instead, it simply documents what
- methods areA supported. Authors should refer to the <a href="#security-developers">Security considerations for authors</a> section of this
- document to better understand the risks and concerns that may arise when using certain
- algorithms.
- </p>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- Note: All algorithms listed should be considered as "features at risk",
- barring implementors adopting them. Their inclusion in the Editor's Draft
- reflects requests for their inclusion by members of the community, and are
- included as an exercise to ensure the robustness of the API defined in this
- specification.
- </p>
- <p>
- As such, the list of algorithms, and the recommendations, may be significantly
- altered in future revisions.
- </p>
- </div>
- <table>
- <thead>
- <tr>
- <th>Algorithm name</th>
- <th scope="col">encrypt</th>
- <th scope="col">decrypt</th>
- <th scope="col">sign</th>
- <th scope="col">verify</th>
- <th scope="col">digest</th>
- <th scope="col">generateKey</th>
- <th scope="col">deriveKey</th>
- <th scope="col">deriveBits</th>
- <th scope="col">importKey</th>
- <th scope="col">exportKey</th>
- <th scope="col">wrapKey</th>
- <th scope="col">unwrapKey</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><a href="#rsassa-pkcs1">RSASSA-PKCS1-v1_5</a></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#rsa-pss">RSA-PSS</a></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#rsa-oaep">RSA-OAEP</a></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#ecdsa">ECDSA</a></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#ecdh">ECDH</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#aes-ctr">AES-CTR</a></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#aes-cbc">AES-CBC</a></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#aes-cmac">AES-CMAC</a></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#aes-gcm">AES-GCM</a></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#aes-cfb">AES-CFB</a></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#aes-kw">AES-KW</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- </tr>
- <tr>
- <td><a href="#hmac">HMAC</a></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#dh">DH</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#sha">SHA-1</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#sha">SHA-256</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#sha">SHA-384</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#sha">SHA-512</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#concatkdf">CONCAT</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#hkdf-ctr">HKDF-CTR</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td><a href="#pbkdf2">PBKDF2</a></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td>✔</td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div id="rsassa-pkcs1" class="section">
- <h3>20. RSASSA-PKCS1-v1_5</h3>
- <div id="rsassa-pkcs1-description" class="section">
- <h4>20.1. Description</h4>
- <p>
- The <code>"RSASSA-PKCS1-v1_5"</code> algorithm identifier is used to perform
- signing and verification using the RSASSA-PKCS1-v1_5 algorithm specified in
- [<cite><a href="#RFC3447">RFC3447</a></cite>] and using the SHA hash functions defined
- in this specification.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with RSASSA-PKCS1-v1_5. Such
- specifications myst define the digest operations for the additional hash algorithms and
- <dfn id="dfn-rsa-ssa-extended-import-steps">key import steps</dfn> and
- <dfn id="dfn-rsa-ssa-extended-export-steps">key export steps</dfn> for RSASSA-PKCS1-v1_5.
- </p>
- </div>
- <div id="rsassa-pkcs1-registration" class="section">
- <h4>20.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"RSASSA-PKCS1-v1_5"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>sign</td>
- <td>None</td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>verify</td>
- <td>None</td>
- <td>boolean</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="RsaKeyGenParams-dictionary" class="section">
- <h4>20.3. RsaKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaKeyGenParams">RsaKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
- <span class="comment">// The length, in bits, of the RSA modulus</span>
- [EnforceRange] required unsigned long <dfn id="dfn-RsaKeyGenParams-modulusLength">modulusLength</dfn>;
- <span class="comment">// The RSA public exponent</span>
- required <a href="#dfn-BigInteger">BigInteger</a> <dfn id="dfn-RsaKeyGenParams-publicExponent">publicExponent</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="RsaHashedKeyGenParams-dictionary" class="section">
- <h4>20.4. RsaHashedKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</dfn> : <a href="#dfn-RsaKeyGenParams">RsaKeyGenParams</a> {
- <span class="comment">// The hash algorithm to use</span>
- required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-RsaHashedKeyGenParams-hash">hash</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="RsaKeyAlgorithm-dictionary" class="section">
- <h4>20.5. RsaKeyAlgorithm dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaKeyAlgorithm">RsaKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
- <span class="comment">// The length, in bits, of the RSA modulus</span>
- required unsigned long <dfn id="dfn-RsaKeyAlgorithm-modulusLength">modulusLength</dfn>;
- <span class="comment">// The RSA public exponent</span>
- required <a href="#dfn-BigInteger">BigInteger</a> <dfn id="dfn-RsaKeyAlgorithm-publicExponent">publicExponent</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="RsaHashedKeyAlgorithm-dictionary" class="section">
- <h4>20.6. RsaHashedKeyAlgorithm dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</dfn> : <a href="#dfn-RsaKeyAlgorithm">RsaKeyAlgorithm</a> {
- <span class="comment">// The hash algorithm that is used with this key</span>
- required <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> <dfn id="dfn-RsaHashedKeyAlgorithm-hash">hash</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="RsaHashedImportParams-dictionary" class="section">
- <h4>20.7. RsaHashedImportParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaHashedImportParams">RsaHashedImportParams</dfn> {
- <span class="comment">// The hash algorithm to use</span>
- required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-RsaHashedImportParams-hash">hash</dfn>;
-};
- </code></pre></div></div>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- Should this be folded into RsaHashedKeyGenParams and rely on the optional nature of the
- dictionary fields?
- </p>
- </div>
- </div>
- <div id="rsassa-pkcs1-operations" class="section">
- <h4>20.8. Operations</h4>
- <dl>
- <dt>Sign</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Perform the signature generation operation defined in Section 8.2 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- as the signer's private key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
- <var>M</var> and using the hash function specified in the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option for the EMSA-PKCS1-v1_5 encoding method.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>signature</var> be the value <var>S</var> that results from
- performing the operation.
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Verify</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Perform the signature verification operation defined in Section 8.2 of
- [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the
- [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> as the signer's RSA public key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
- <var>M</var> and the <a href="#concept-contents-of-arraybuffer">contents of
- <var>signature</var></a> as <var>S</var> and using the hash function specified
- in the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option for the EMSA-PKCS1-v1_5 encoding method.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a boolean with value true if the
- result of the operations was "valid signature" and a boolean with value
- false otherwise.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> attribute of
- <var>normalizedAlgorithm</var> and RSA public exponent equal to the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> attribute of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If generation of the key pair fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSASSA-PKCS1-v1_5"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
- attribute of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
- attribute of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
- of <var>algorithm</var> to equal the
- <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to be <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to be <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object, as
- defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- TODO: Specify the mapping between key.algorithm.hash and the appropriate Hash
- functions (and back to OID).
- </p>
- </div>
- </dd>
-
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the
- <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>algorithm</code> AlgorithmIdentifier field of
- <var>spki</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in Section 2.3.1 of <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha1WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha256WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha384WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha512WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
- <var>structure</var> as the <code>RSAPublicKey</code> structure
- specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA public key identified by
- <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>privateKeyAlgorithm</code>
- PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in Section 2.3.1 of <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha1WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha256WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha384WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>sha512WithRSAEncryption</code> OID defined in Section A.2.4 of
- <a href="#RFC3279">RFC 3279</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>privateKey</code> field of <var>privateKeyInfo</var>,
- <var>structure</var> as the <code>RSAPrivateKey</code> structure
- specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA private key identified by
- <var>rsaPrivateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field of <var>jwk</var> is present and
- <var>usages</var> contains an entry which is not
- <code>"sign"</code>, or, if the <code>"d"</code> field of <var>jwk</var>
- is not present and
- <var>usages</var> contains an entry which is not
- <code>"verify"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not a
- case-sensitive string match to <code>"RSA"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not a case-sensitive string match to <code>"sig"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be a be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is not
- present:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"RS1"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"RS256"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"RS384"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"RS512"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.3.2 of <a href="#jwa">JSON Web
- Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA private key identified by interpreting <var>jwk</var>
- according to Section 6.3.2 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA public key identified by interpreting <var>jwk</var>
- according to Section 6.3.1 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a> dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSASSA-PKCS1-v1_5"</code>
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to the length, in bits, of the RSA public
- modulus.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
- representation of the RSA public exponent.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
- <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>Return <var>key</var>.</p>
- </li>
- </ol>
- </dd>
-
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>key</var> be the key to be exported.
- </p>
- </li>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code></dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>1.2.840.113549.1.1</code>
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to the ASN.1 type NULL.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> field to the result of
- DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
- in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
- represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>version</var> field to 0.
- </p>
- </li>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to a
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>1.2.840.113549.1.1</code>
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to the ASN.1 type NULL.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to the result of DER-encoding
- an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
- RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
- this field should be <em>BER</em> encoded in Section 5 (as a "for
- example"). However, to avoid requiring WebCrypto implementations
- support BER-encoding and BER-decoding, only <em>DER</em> encodings
- are produced or accepted.
- </div>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ul>
- <li>
- <p>Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.</p>
- </li>
- <li>
- <p>Set the <code>kty</code> attribute of <var>jwk</var> to the string
- <code>"RSA"</code>.</p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
- attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>hash</var> is <code>"SHA-1"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RS1"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-256"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RS256"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-384"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RS384"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-512"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RS512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-ssa-extended-export-steps">key
- export steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>key</var>
- and obtaining <var>alg</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
- according to the corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.1.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"private"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Set the attributes named <code>d</code>, <code>p</code>,
- <code>q</code>, <code>dp</code>, <code>dq</code>, and
- <code>qi</code> of <var>jwk</var> according to the
- corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.2.
- </p>
- </li>
- <li>
- <p>
- If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var> is represented by more than two primes, set
- the attribute named <code>oth</code> of <var>jwk</var>
- according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ul>
- </dd>
- <dt>Otherwise</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="rsa-pss" class="section">
- <h3>21. RSA-PSS</h3>
- <div id="rsa-pss-description" class="section">
- <h4>21.1. Description</h4>
- <p>
- The <code>"RSA-PSS"</code> algorithm identifier is used to perform signing
- and verification using the RSASSA-PSS algorithm specified in
- [<cite><a href="#RFC3447">RFC3447</a></cite>], using the SHA hash functions defined
- in this specification and the mask generation
- formula MGF1.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with RSASSA-PSS. Such specifications
- must define the digest operation for the additional hash algorithms and
- <dfn id="dfn-rsa-pss-extended-import-steps">key import steps</dfn> and
- <dfn id="dfn-rsa-pss-extended-export-steps">key export steps</dfn> for RSASSA-PSS.
- </p>
- </div>
- <div id="rsa-pss-registration" class="section">
- <h4>21.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"RSA-PSS"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>sign</td>
- <td><a href="#dfn-RsaPssParams">RsaPssParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>verify</td>
- <td><a href="#dfn-RsaPssParams">RsaPssParams</a></td>
- <td>boolean</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="RsaPssParams-dictionary" class="section">
- <h4>21.3. RsaPssParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaPssParams">RsaPssParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The desired length of the random salt</span>
-[EnforceRange] required unsigned long <dfn id="dfn-RsaPssParams-saltLength">saltLength</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="rsa-pss-operations" class="section">
- <h4>21.4. Operations</h4>
- <dl>
- <dt>Sign</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Perform the signature generation operation defined in Section 8.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- as the signer's private key, <var>K</var>, and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
- the message to be signed, <var>M</var>, and using the hash function specified
- by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option, MGF1 (defined in Section B.2.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option and the <a href="#dfn-RsaPssParams-saltLength">saltLength</a> member of
- <var>normalizedAlgorithm</var> as the salt length option for the
- EMM-PSS-ENCODE operation.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>signature</var> be a new <code>ArrayBuffer</code> containing the
- signature, S, that results from performing the operation.
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Verify</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Perform the signature verification operation defined in Section 8.1 of
- [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the
- [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> as the signer's RSA public key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
- <var>M</var> and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>signature</var></a> as <var>S</var> and using the hash function specified
- by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option, MGF1 (defined in Section B.2.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option and the <a href="#dfn-RsaPssParams-saltLength">saltLength</a> member of
- <var>normalizedAlgorithm</var> as the salt length option for the
- EMSA-PSS-VERIFY operation.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a boolean with value true if the
- result of the operation was "valid signature" and a boolean with value
- false otherwise.
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> member of
- <var>normalizedAlgorithm</var> and RSA public exponent equal to the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSA-PSS"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
- of <var>algorithm</var> to equal the
- <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object,
- as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"verify"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the
- <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>algorithm</code> AlgorithmIdentifier field of
- <var>spki</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the
- <code>id-RSASSA-PSS</code> OID defined in
- <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>params</var> be the ASN.1 structure contained within
- the <code>parameters</code> field of the <code>algorithm</code>
- AlgorithmIdentifier field of <var>spki</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not defined, or is not an instance of
- the <code>RSASSA-PSS-params</code> ASN.1 type defined in
- <a href="#RFC3447">RFC3447</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
- within the <code>hashAlgorithm</code> field of <var>params</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
-
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- an instance of the <code>HashAlgorithm</code> ASN.1 type that is
- identical in content to the <code>hashAlglorithm</code> field of
- <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
- <var>structure</var> as the <code>RSAPublicKey</code> structure
- specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA public key identified by
- <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>privateKeyAlgorithm</code>
- PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the <code>id-RSASSA-PSS</code> OID
- defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>params</var> be the ASN.1 structure contained within
- the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier
- field of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not defined, or is not an instance of
- the <code>RSASSA-PSS-params</code> ASN.1 type defined in
- <a href="#RFC3447">RFC3447</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
- within the <code>hashAlgorithm</code> field of <var>params</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- an instance of the <code>HashAlgorithm</code> ASN.1 type that is
- identical in content to the <code>hashAlglorithm</code> field of
- <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>privateKey</code> field of <var>privateKeyInfo</var>,
- <var>structure</var> as the <code>RSAPrivateKey</code> structure
- specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA private key identified by
- <var>rsaPrivateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field of <var>jwk</var> is present and
- <var>usages</var> contains an entry which is not
- <code>"sign"</code>, or, if the <code>"d"</code> field of <var>jwk</var>
- is not present and
- <var>usages</var> contains an entry which is not
- <code>"verify"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not a
- case-sensitive string match to <code>"RSA"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not a case-sensitive string match to <code>"sig"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is not
- present:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"PS1"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"PS256"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"PS384"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string
- <code>"PS512"</code>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.3.2 of <a href="#jwa">JSON Web
- Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA private key identified by interpreting <var>jwk</var>
- according to Section 6.3.2 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA public key identified by interpreting <var>jwk</var>
- according to Section 6.3.1 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a> dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSA-PSS"</code>
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to the length, in bits, of the RSA public
- modulus.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
- representation of the RSA public exponent.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
- <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>
- </p>
- </li>
- <li>
- <p>Return <var>key</var>.</p>
- </li>
- </ol>
- </dd>
-
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>key</var> be the key to be exported.
- </p>
- </li>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code></dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-RSASSA-PSS</code> defined in
- <a href="#RFC3447">RFC 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>RSASSA-PSS-params</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>hashAlgorithm</var> field to an instance of
- the <code>HashAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-1"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-256"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-384"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-512"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>hashOid</var> and <var>hashParams</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to <var>hashOid</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field of <var>hashAlgorithm</var>
- to
- <var>hashParams</var> if <var>hashParams</var> is not
- undefined and omit the <var>params</var> field otherwise.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <var>maskGenAlgorithm</var> field to an instance
- of the <code>MaskGenAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
- 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>HashAlgorithm</code> ASN.1 type that is
- identical to the <var>hashAlgorithm</var> field.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>saltLength</var> field to the length in
- octets of the digest algorithm identified by the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
- of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> field to the result of
- DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
- in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
- represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>version</var> field to 0.
- </p>
- </li>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to an
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-RSASSA-PSS</code> defined in
- <a href="#RFC3447">RFC 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>RSASSA-PSS-params</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>hashAlgorithm</var> field to an instance of
- the <code>HashAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-1"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-256"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-384"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-512"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>hashOid</var> and <var>hashParams</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to <var>hashOid</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field of <var>hashAlgorithm</var>
- to
- <var>hashParams</var> if <var>hashParams</var> is not
- undefined and omit the <var>params</var> field otherwise.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <var>maskGenAlgorithm</var> field to an instance
- of the <code>MaskGenAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
- 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>HashAlgorithm</code> ASN.1 type that is
- identical to the <var>hashAlgorithm</var> field.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>saltLength</var> field to the length in
- octets of the digest algorithm identified by the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
- of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to the result of DER-encoding
- an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
- RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
- this field should be <em>BER</em> encoded in Section 5 (as a "for
- example"). However, to avoid requiring WebCrypto implementations
- support BER-encoding and BER-decoding, only <em>DER</em> encodings
- are produced or accepted.
- </div>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ul>
- <li>
- <p>Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary.</p>
- </li>
- <li>
- <p>Set the <code>kty</code> attribute of <var>jwk</var> to the string
- <code>"RSA"</code>.</p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>hash</var> is <code>"SHA-1"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"PS1"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-256"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"PS256"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-384"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"PS384"</code>.
- </p>
- </dd>
- <dt>If <var>hash</var> is <code>"SHA-512"</code>:</dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"PS512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>alg</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
- according to the corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.1.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is <code>"private"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Set the attributes named <code>d</code>, <code>p</code>,
- <code>q</code>, <code>dp</code>, <code>dq</code>, and
- <code>qi</code> of <var>jwk</var> according to the
- corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.2.
- </p>
- </li>
- <li>
- <p>
- If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var> is represented by more than two primes, set
- the attribute named <code>oth</code> of <var>jwk</var>
- according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ul>
- </dd>
- <dt>Otherwise</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="rsa-oaep" class="section">
- <h3>22. RSA-OAEP</h3>
- <div id="rsa-oaep-description" class="section">
- <h4>22.1. Description</h4>
- <p>
- The <code>"RSA-OAEP"</code> algorithm identifier is used to perform encryption
- and decryption ordering to the RSAES-OAEP algorithm specified in
- [<cite><a href="#RFC3447">RFC3447</a></cite>], using the SHA hash functions defined
- in this specification and using the mask
- generation function MGF1.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with RSAES-OAEP. Such specifications
- must define the digest operation for the additional hash algorithm and
- <dfn id="dfn-rsa-oaep-extended-import-steps">key import steps</dfn> and
- <dfn id="dfn-rsa-oaep-extended-export-steps">key export steps</dfn> for RSAES-OAEP.
- </p>
- </div>
- <div id="rsa-oaep-registration" class="section">
- <h4>22.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"RSA-OAEP"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>encrypt</td>
- <td><a href="#dfn-RsaOaepParams">RsaOaepParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>decrypt</td>
- <td><a href="#dfn-RsaOaepParams">RsaOaepParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div id="rsa-oaep-params" class="section">
- <h4>22.3. RsaOaepParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-RsaOaepParams">RsaOaepParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The optional label/application data to associate with the message</span>
-BufferSource <dfn id="dfn-RsaOaepParams-label">label</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="rsa-oaep-operations" class="section">
- <h4>22.4. Operations</h4>
- <dl>
- <dt>Encrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of <var>key</var>
- is not <code>"public"</code>,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>label</var> be the <a href="#concept-contents-of-arraybuffer">contents of</a> the <a href="#dfn-RsaOaepParams-label">label</a> member of
- <var>normalizedAlgorithm</var> or the empty octet string if the
- <a href="#dfn-RsaOaepParams-label">label</a> member of
- <var>normalizedAlgorithm</var> is not present.
- </p>
- </li>
- <li>
- <p>
- Perform the encryption operation defined in Section 7.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by <var>key</var>
- as the recipient's RSA public key, the <a href="#concept-contents-of-arraybuffer">contents of <var>plaintext</var></a>
- as the message to be encrypted, <var>M</var> and <var>label</var>
- as the label, <var>L</var>, and with the hash
- function specified by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option and MGF1 (defined in Section B.2.1 of
- [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be a new <code>ArrayBuffer</code>
- containing the value <var>C</var> that results from performing the
- operation.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Decrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of <var>key</var>
- is not <code>"private"</code>,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>label</var> be the <a href="#concept-contents-of-arraybuffer">contents of</a> the <a href="#dfn-RsaOaepParams-label">label</a> member of
- <var>normalizedAlgorithm</var> or the empty octet string if the
- <a href="#dfn-RsaOaepParams-label">label</a> member of
- <var>normalizedAlgorithm</var> is not present.
- </p>
- </li>
- <li>
- <p>
- Perform the decryption operation defined in Section 7.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by <var>key</var>
- as the recipient's RSA private key, the <a href="#concept-contents-of-arraybuffer">contents of <var>ciphertext</var></a>
- as the ciphertext to be decrypted, C, and <var>label</var>
- as the label, <var>L</var>, and with the hash
- function specified by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> as the Hash option and MGF1 (defined in Section B.2.1 of
- [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>plaintext</var> be a new <code>ArrayBuffer</code>
- containing the value <var>M</var> that results from performing the
- operation.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> member of
- <var>normalizedAlgorithm</var> and RSA public exponent equal to the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSA-OAEP"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the
- <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
- of <var>algorithm</var> to equal the
- <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot of
- <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the
- <a href="#concept-usage-intersection">usage intersection</a> of
- <var>usages</var> and <code>[ "encrypt", "wrapKey" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot of
- <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be the
- <a href="#concept-usage-intersection">usage intersection</a> of
- <var>usages</var> and <code>[ "decrypt", "unwrapKey" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to be <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to be <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object, as
- defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"encrypt"</code> or
- <code>"wrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the
- <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be a string whose initial value is undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>algorithm</code> AlgorithmIdentifier field of
- <var>spki</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the <code>id-RSAES-OAEP</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>params</var> be the ASN.1 structure contained within
- the <code>parameters</code> field of the <code>algorithm</code>
- AlgorithmIdentifier field of <var>spki</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not defined, or is not an instance of
- the <code>RSAES-OAEP-params</code> ASN.1 type defined in
- <a href="#RFC3447">RFC3447</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
- within the <code>hashAlgorithm</code> field of <var>params</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-oeap-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- an instance of the <code>HashAlgorithm</code> ASN.1 type that is
- identical in content to the <code>hashAlglorithm</code> field of
- <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
- <var>structure</var> as the <code>RSAPublicKey</code> structure
- specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA public key identified by
- <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"decrypt"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be a string whose initial value is undefined.
- </p>
- </li>
- <li>
- <p>
- Let <var>alg</var> be the <code>algorithm</code> object identifier
- field of the <code>privateKeyAlgorithm</code>
- PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Let <var>hash</var> be undefined.
- </p>
- </dd>
- <dt>
- If <var>alg</var> is equivalent to the <code>id-RSAES-OAEP</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>params</var> be the ASN.1 structure contained within
- the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier
- field of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not defined, or is not an instance of
- the <code>RSAES-OAEP-params</code> ASN.1 type defined in <a href="#RFC3447">RFC3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
- within the <code>hashAlgorithm</code> field of
- <var>params</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
- OID defined in <a href="#RFC3447">RFC 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-1"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the
- <code>id-sha256</code> OID defined in <a href="#RFC3447">RFC
- 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-256"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the
- <code>id-sha384</code> OID defined in <a href="#RFC3447">RFC
- 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-384"</code>.
- </p>
- </dd>
- <dt>
- If the <code>algorithm</code> object identifier field of
- <var>hashAlg</var> is equivalent to the
- <code>id-sha512</code> OID defined in <a href="#RFC3447">RFC
- 3447</a>:
- </dt>
- <dd>
- <p>
- Set <var>hash</var> to the string <code>"SHA-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-oeap-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>maskGenAlgorithm</code> field of <var>params</var> is not
- an instance of the <code>HashAlgorithm</code> ASN.1 type that is
- identical in content to the <code>hashAlglorithm</code> field of
- <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the
- <code>privateKey</code> field of <var>privateKeyInfo</var>,
- <var>structure</var> as the <code>RSAPrivateKey</code> structure
- specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
- <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the RSA private key identified by
- <var>rsaPrivateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field of <var>jwk</var> is present and
- <var>usages</var> contains an entry which is not
- <code>"decrypt"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field of <var>jwk</var> is not present and
- <var>usages</var> contains an entry which is not
- <code>"encrypt"</code> or <code>"wrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not a
- case-sensitive string match to <code>"RSA"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not a case-sensitive string match to <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>alg</code> field of <var>jwk</var> is not present:</dt>
- <dd>Let <var>hash</var> be undefined.</dd>
- <dt>
- If the <code>alg</code> field of <var>jwk</var> is equal to
- <code>"RSA-OAEP"</code>:
- </dt>
- <dd>Let <var>hash</var> be the string <code>"SHA-1"</code>.</dd>
- <dt>
- If the <code>alg</code> field of <var>jwk</var> is equal to
- <code>"RSA-OAEP-256"</code>:
- </dt>
- <dd>Let <var>hash</var> be the string <code>"SHA-256"</code>.</dd>
- <dt>
- If the <code>alg</code> field of <var>jwk</var> is equal to
- <code>"RSA-OAEP-384"</code>:
- </dt>
- <dd>Let <var>hash</var> be the string <code>"SHA-384"</code>.</dd>
- <dt>
- If the <code>alg</code> field of <var>jwk</var> is equal to
- <code>"RSA-OAEP-512"</code>:
- </dt>
- <dd>Let <var>hash</var> be the string <code>"SHA-512"</code>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-oaep-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and obtaining <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl>
- <dt>
- If <var>hash</var> is not undefined:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>normalizedHash</var> be the result of
- <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
- with <code>alg</code> set to <var>hash</var> and <code>op</code> set
- to <code>digest</code>.
- </p>
- </li>
- <li>
- <p>
- If <var>normalizedHash</var> is not equal to the
- <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.3.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA private key identified by interpreting <var>jwk</var>
- according to Section 6.3.2 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"private"</code>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- RSA public key identified by interpreting <var>jwk</var>
- according to Section 6.3.1 of <a href="#jwa"> JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"public"</code>
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"RSA-OAEP"</code>
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
- attribute of <var>algorithm</var> to the length, in bits, of the RSA public
- modulus.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
- attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
- representation of the RSA public exponent.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
- <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> to <var>algorithm</var>
- </p>
- </li>
- <li>
- <p>Return <var>key</var>.</p>
- </li>
- </ol>
- </dd>
-
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>key</var> be the key to be exported.
- </p>
- </li>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> a <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code></dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-RSAES-OAEP</code> defined in
- <a href="#RFC3447">RFC 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>RSAES-OAEP-params</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>hashAlgorithm</var> field to an instance of
- the <code>HashAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-1"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-256"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-384"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-512"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>hashOid</var> and <var>hashParams</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to <var>hashOid</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field of <var>hashAlgorithm</var>
- to
- <var>hashParams</var> if <var>hashParams</var> is not
- undefined and omit the <var>params</var> field otherwise.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <var>maskGenAlgorithm</var> field to an instance
- of the <code>MaskGenAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
- 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>HashAlgorithm</code> ASN.1 type that is
- identical to the <var>hashAlgorithm</var> field.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> field to the result of
- DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
- in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
- represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>version</var> field to 0.
- </p>
- </li>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to an
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-RSAES-OAEP</code> defined in
- <a href="#RFC3447">RFC 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>RSAES-OAEP-params</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>hashAlgorithm</var> field to an instance of
- the <code>HashAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-1"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-256"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-384"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a>
- attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"SHA-512"</code>:
- </dt>
- <dd>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to the
- OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-oaep-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>hashOid</var> and <var>hashParams</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier
- of <var>hashAlgorithm</var> to <var>hashOid</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field of <var>hashAlgorithm</var>
- to
- <var>hashParams</var> if <var>hashParams</var> is not
- undefined and omit the <var>params</var> field otherwise.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <var>maskGenAlgorithm</var> field to an instance
- of the <code>MaskGenAlgorithm</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the OID
- <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
- 3447</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>params</var> field to an instance of the
- <code>HashAlgorithm</code> ASN.1 type that is
- identical to the <var>hashAlgorithm</var> field.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to the result of DER-encoding
- an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
- RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>
- </p>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
- this field should be <em>BER</em> encoded in Section 5 (as a "for
- example"). However, to avoid requiring WebCrypto implementations
- support BER-encoding and BER-decoding, only <em>DER</em> encodings
- are produced or accepted.
- </div>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ul>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the string
- <code>"RSA"</code>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"SHA-1"</code>:
- </dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RSA-OAEP"</code>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"SHA-256"</code>:
- </dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RSA-OAEP-256"</code>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"SHA-384"</code>:
- </dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RSA-OAEP-384"</code>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"SHA-512"</code>:
- </dt>
- <dd>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to the string
- <code>"RSA-OAEP-512"</code>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-rsa-oaep-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>alg</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
- according to the corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.1.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"private"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Set the attributes named <code>d</code>, <code>p</code>,
- <code>q</code>, <code>dp</code>, <code>dq</code>, and
- <code>qi</code> of <var>jwk</var> according to the
- corresponding definitions in <a href="#jwa">JSON Web
- Algorithms</a>, Section 6.3.2.
- </p>
- </li>
- <li>
- <p>
- If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var> is represented by more than two primes, set
- the attribute named <code>oth</code> of <var>jwk</var>
- according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ul>
- </dd>
- <dt>Otherwise</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="ecdsa" class="section">
- <h3>23. ECDSA</h3>
- <div id="ecdsa-description" class="section">
- <h4>23.1. Description</h4>
- <p>
- The <code>"ECDSA"</code> algorithm identifier is used to perform signing
- and verification using the ECDSA algorithm specified in
- [<cite><a href="#X9.62">X9.62</a></cite>] and using the SHA hash functions and elliptic
- curves defined in this specification.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional elliptic curves and hash algorithms with ECDSA. To
- specify additional hash algorithms to be used with ECDSA, a specification must define
- a <a href="#algorithms">registered algorithm</a> that supports the digest operation.
- To specify an additional elliptic curve a specification must define
- <dfn id="dfn-ecdsa-extended-namedcurve-values">the curve name</dfn>,
- <dfn id="dfn-ecdsa-extended-signature-steps">ECDSA signature steps</dfn>,
- <dfn id="dfn-ecdsa-extended-verification-steps">ECDSA verification steps</dfn>,
- <dfn id="dfn-ecdsa-extended-generation-steps">ECDSA generation steps</dfn>,
- <dfn id="dfn-ecdsa-extended-import-steps">ECDSA key import steps</dfn> and
- <dfn id="dfn-ecdsa-extended-verification-steps">ECDSA key export steps</dfn>.
- </p>
- </div>
- <div id="ecdsa-registration" class="section">
- <h4>23.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"ECDSA"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>sign</td>
- <td><a href="#dfn-EcdsaParams">EcdsaParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>verify</td>
- <td><a href="#dfn-EcdsaParams">EcdsaParams</a></td>
- <td>boolean</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-EcKeyGenParams">EcKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-EcKeyImportParams">EcKeyImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
-
- </tbody>
- </table>
- </div>
- <div id="EcdsaParams-dictionary" class="section">
- <h4>23.3. EcdsaParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-EcdsaParams">EcdsaParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The hash algorithm to use</span>
-required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-EcdsaParams-hash">hash</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="EcKeyGenParams-dictionary" class="section">
- <h4>23.4. EcKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-typedef DOMString <a href="#dfn-NamedCurve">NamedCurve</a>;
-
-dictionary <dfn id="dfn-EcKeyGenParams">EcKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// A named curve</span>
-required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyGenParams-namedCurve">namedCurve</dfn>;
-};
- </code></pre></div></div>
- <p>
- The <dfn id="dfn-NamedCurve">NamedCurve</dfn> type represents named elliptic curves,
- which are a convenient way to specify the domain parameters of well-known elliptic
- curves. The following values defined by this specification:
- </p>
- <dl>
- <dt id="dfn-NamedCurve-p256"><code>"P-256"</code></dt>
- <dd>NIST recommended curve P-256, also known as <code>secp256r1</code>.</dd>
- <dt id="dfn-NamedCurve-p2384"><code>"P-384"</code></dt>
- <dd>NIST recommended curve P-384, also known as <code>secp384r1</code>.</dd>
- <dt id="dfn-NamedCurve-p521"><code>"P-521"</code></dt>
- <dd>NIST recommended curve P-521, also known as <code>secp521r1</code>.</dd>
- </dl>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a> may define
- <a href="#dfn-ecdsa-extended-namedcurve-values">additional values</a>.
- </p>
- </div>
- <div id="EcKeyAlgorithm-dictionary" class="section">
- <h4>23.5. EcKeyAlgorithm dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-EcKeyAlgorithm">EcKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
-<span class="comment">// The named curve that the key uses</span>
-required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyAlgorithm-namedCurve">namedCurve</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="EcKeyImportParams-dictionary" class="section">
- <h4>23.6. EcKeyImportParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-EcKeyImportParams">EcKeyImportParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// A named curve</span>
-required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyImportParams-namedCurve">namedCurve</dfn>;
-};
- </code></pre></div></div>
- </div>
-
- <div id="ecdsa-operations" class="section">
- <h4>23.7. Operations</h4>
- <dl>
- <dt>Sign</dt>
- <dd>
- When signing, the following algorithm should be used:
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlgorithm</var> be the <a href="#dfn-EcdsaParams-hash">hash</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>hashAlgorithm</var> does not describe a
- <a href="#algorithms">registered algorithm</a> that supports the digest
- operation,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>M</var> be the result of performing the digest operation specified by
- <var>hashAlgorithm</var> using <var>message</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>d</var> be the ECDSA private key associated with <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the EC domain parameters associated with
- <var>key</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform the ECDSA signing process, as specified in <a href="#X9.62">X9.62</a>,
- Section 7.3, with <var>M</var> as the message, using <var>params</var> as the
- EC domain parameters, and with <var>d</var> as the private key.
- </p>
- </li>
- <li>
- <p>
- Let <var>r</var> and <var>s</var> be the pair of integers resulting from
- performing the ECDSA signing process.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code>.
- </p>
- </li>
- <li>
- <p>
- Convert <var>r</var> to a bitstring and append the sequence of bytes to
- <var>result</var>.
- </p>
- </li>
- <li>
- <p>
- Convert <var>s</var> to a bitstring and append the sequence of bytes to
- <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- Otherwise, the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute
- of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is a value specified in an
- <a href="#dfn-applicable-specification">applicable specification</a>:
- </dt>
- <dd>
- <p>
- Perform the <a href="#dfn-ecdsa-extended-signature-steps">ECDSA signature steps</a>
- specified in that specification, passing in <var>M</var>, <var>params</var>
- and <var>d</var> and resulting in <var>result</var>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Verify</dt>
- <dd>
- When verifying, the following algorithm should be used:
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hashAlgorithm</var> be the <a href="#dfn-EcdsaParams-hash">hash</a>
- member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>hashAlgorithm</var> does not describe a
- <a href="#algorithms">registered algorithm</a> that supports the digest
- operation,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>M</var> be the result of performing the digest operation specified by
- <var>hashAlgorithm</var> using <var>message</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>Q</var> be the ECDSA public key associated with <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the EC domain parameters associated with
- <var>key</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Perform the ECDSA verifying process, as specified in <a href="#X9.62">X9.62</a>, Section 7.4, with <var>M</var> as the received
- message, <var>signature</var> as the received signature and using
- <var>params</var> as the EC domain parameters, and
- <var>Q</var> as the public key.
- </p>
- </dd>
- <dt>
- Otherwise, the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute
- of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is a value specified in an
- <a href="#dfn-applicable-specification">applicable specification</a>:
- </dt>
- <dd>
- <p>
- Perform the <a href="#dfn-ecdsa-extended-verification-steps">ECDSA verification steps</a>
- specified in that specification passing in <var>M</var>, <var>signature</var>,
- <var>params</var> and <var>Q</var> and resulting in an indication of whether
- or not the purported signature is valid.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>result</var> be a boolean indicating whether or not the purported
- signature is valid, with <code>true</code> indicating the signature is valid
- and <code>false</code> indicating it is invalid.
- </p>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value which is not
- one of <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> is <code>"P-256"</code>, <code>"P-384"</code>
- or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Generate an Elliptic Curve key pair, as defined in [<a href="#X9.62">X9.62</a>]
- with domain parameters for the curve identified by
- the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> is a value specified in an
- <a href="#dfn-applicable-specification">applicable specification</a>:
- </dt>
- <dd>
- <p>
- Perform the <a href="#dfn-ecdsa-extended-generation-steps">ECDSA key
- generation steps</a> specified in that specification, passing in
- <var>normalizedAlgorithm</var> and resulting in an elliptic curve key pair.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If performing the key generation operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDSA"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-EcKeyGenParams">namedCurve</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
- intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to be <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to be <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object, as
- defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value which is not
- <code>"verify"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the
- <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
- algorithm over <var>keyData</var>
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is
- not equal to the <code>id-ecPublicKey</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the <code>algorithm</code>
- AlgorithmIdentifier field of <var>spki</var> is absent,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> that specifies a
- <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>params</var> is equivalent to the <code>secp256r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp384r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp521r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-521"</code>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>namedCurve</var> is not undefined:</dt>
- <dd>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the Elliptic Curve public key identified by
- performing the conversion steps defined in Section 2.2 of <a href="#RFC5480">RFC 5480</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>namedCurve</var> and <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the public key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDSA"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value which is not
- <code>"sign"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurs while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithm field of
- <var>privateKeyInfo</var> is not equal to the
- <code>id-ecPublicKey</code> object identifier defined in <a href="#RFC5480">RFC 5480</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var> is not present,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> that specifies a
- <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>params</var> is equivalent to the <code>secp256r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp384r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp521r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-521"</code>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>namedCurve</var> is not undefined:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>ecPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the <code>privateKey</code> field
- of <var>privateKeyInfo</var>, <var>structure</var> as the ASN.1
- <code>ECPrivateKey</code> structure specified in Section 3 of <a href="#RFC5915">RFC 5915</a>, and <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of <var>ecPrivateKey</var> is
- present, and is not an instance of the <code>namedCurve</code> ASN.1
- type defined in <a href="#RFC5480">RFC 5480</a>, or does not contain
- the same object identifier as the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the Elliptic Curve private key identified by
- performing the conversion steps defined in Section 3 of <a href="#RFC5915">RFC 5915</a> using <var>ecPrivateKey</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
- and obtaining <var>namedCurve</var> and <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the private key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDSA"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field is present and <var>usages</var> contains
- a value which is not
- <code>"sign"</code>, or,
- if the <code>"d"</code> field is not present and <var>usages</var> contains
- a value which is not
- <code>"verify"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"EC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"sig"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of <a href="#jwk">JSON Web
- Key</a>, or it does not contain all of the specified <var>usages</var>
- values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose value is equal to the
- <code>"crv"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>namedCurve</var> is equal to <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>algNamedCurve</var> be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>"alg"</code> field is not present:</dt>
- <dd>
- Let <var>algNamedCurve</var> be undefined.
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string "ES256":
- </dt>
- <dd>
- Let <var>algNamedCurve</var> be the string <code>"P-256"</code>.
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string "ES384":
- </dt>
- <dd>
- Let <var>algNamedCurve</var> be the string <code>"P-384"</code>.
- </dd>
- <dt>
- If the <code>"alg"</code> field is equal to the string "ES521":
- </dt>
- <dd>
- Let <var>algNamedCurve</var> be the string <code>"P-521"</code>.
- </dd>
- <dt>otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>algNamedCurve</var> is defined, and is not equal to
- <var>namedCurve</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <code>"d"</code> field is present:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- Elliptic Curve private key identified by interpreting
- <var>jwk</var> according to Section 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>Key</var> to <code>"private"</code>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- Elliptic Curve public key identified by interpreting
- <var>jwk</var> according to Section 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>Key</var> to <code>"public"</code>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and obtaining <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new instance of an <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDSA"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>key</var>
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>key</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> to be
- exported.
- </p>
- </li>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier to the OID
- <code>1.2.840.10045.2.1</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> as follows:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Let <var>keyData</var> be the
- <a href="#dfn-octet-string">octet string</a> that
- represents the Elliptic Curve public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> according to the encoding rules specified in
- Section 2.2 of <a href="#RFC5480">RFC 5480</a> and using the
- uncompressed form. and <var>keyData</var>.
- </p>
- <p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp256r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp384r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp521r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- </dl>
- </p>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier <var>namedCurveOid</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> field to <var>keyData</var>.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>version</var> field to <code>0</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to an
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier to the OID
- <code>1.2.840.10045.2.1</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> as follows:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Let <var>keyData</var> be the result of DER-encoding
- an instance of the <code>ECPrivateKey</code> structure defined in
- Section 3 of <a href="#RFC5915">RFC 5915</a> for the Elliptic
- Curve private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> and that conforms to the following:
- </p>
- <ul>
- <li>
- <p>
- The <var>parameters</var> field is present, and is equivalent
- to the <var>parameters</var> field of the
- <var>privateKeyAlgorithm</var> field of this
- <code>PrivateKeyInfo</code> ASN.1 structure.
- </p>
- </li>
- <li>
- <p>
- The <var>publicKey</var> field is present and represents the
- Elliptic Curve public key associated with the Elliptic Curve
- private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- </ul>
- <p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp256r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp384r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier
- <code>secp521r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- </dl>
- </p>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier <var>namedCurveOid</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to <var>keyData</var>.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to
- <code>"EC"</code>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or
- <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-256"</code>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-384"</code>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-521"</code>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>x</code> attribute of <var>jwk</var> according to the
- definition in Section 6.2.1.2 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>y</code> attribute of <var>jwk</var> according to the
- definition in Section 6.2.1.3 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"private"</code>
- </dt>
- <dd>
- <p>
- Set the <code>d</code> attribute of <var>jwk</var> according to
- the definition in Section 6.2.2.1 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurve</var> and a new value of <var>jwk</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <var>namedCurve</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="ecdh" class="section">
- <h3>24. ECDH</h3>
- <div id="ecdh-description" class="section">
- <h4>24.1. Description</h4>
- <p>
- This describes using Elliptic Curve Diffie-Hellman (ECDH) for key generation and key
- agreement, as specified by <a href="#X9.63">X9.63</a>.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional elliptic curves with ECDH.
- To specify an additional elliptic curve a specification must define
- <dfn id="dfn-ecdh-extended-namedcurve-values">the curve name</dfn>,
- <dfn id="dfn-ecdh-extended-generation-steps">ECDH generation steps</dfn>,
- <dfn id="dfn-ecdh-extended-derivation-steps">ECDH derivation steps</dfn>,
- <dfn id="dfn-ecdh-extended-import-steps">ECDH key import steps</dfn> and
- <dfn id="dfn-ecdh-extended-verification-steps">ECDH key export steps</dfn>.
- </p>
- </div>
- <div id="ecdh-registration" class="section">
- <h4>24.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"ECDH"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-EcKeyGenParams">EcKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>deriveBits</td>
- <td><a href="#dfn-EcdhKeyDeriveParams">EcdhKeyDeriveParams</a></td>
- <td><a href="#dfn-octet-string">Octet string</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-EcKeyImportParams">EcKeyImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="dh-EcdhKeyDeriveParams" class="section">
- <h4>24.3. EcdhKeyDeriveParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-EcdhKeyDeriveParams">EcdhKeyDeriveParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The peer's EC public key.</span>
-required <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-EcdhKeyDeriveParams-public">public</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="ecdh-operations" class="section">
- <h4>24.4. Operations</h4>
- <dl>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> is <code>"P-256"</code>, <code>"P-384"</code>
- or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Generate an Elliptic Curve key pair, as defined in [<a href="#X9.63">X9.63</a>] with domain parameters for the curve identified by
- the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> is a value specified in an
- <a href="#dfn-applicable-specification">applicable specification</a> that
- specifies the use of that value with ECDH:
- </dt>
- <dd>
- <p>
- Perform the <a href="#dfn-ecdh-extended-generation-steps">ECDH key
- generation steps</a> specified in that specification, passing in
- <var>normalizedAlgorithm</var> and resulting in an elliptic curve key pair.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-Algorithm-name">name</a> member of
- <var>algorithm</var> to <code>"ECDH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-EcKeyGenParams">namedCurve</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the empty list.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be the
- <a href="#concept-usage-intersection">usage intersection</a> of
- <var>usages</var> and <code>[ "deriveKey", "deriveBits" ]</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to be <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to be <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object, as
- defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Derive Bits</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be the
- <a href="#dfn-EcdhKeyDeriveParams-public">public</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>publicKey</var> is not equal to the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
- or <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform the ECDH primitive specified in <a href="#X9.63">X9.63</a> Section
- 5.4.1 with <var>key</var> as the EC private key <var>d</var> and the EC public
- key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
- internal slot of <var>publicKey</var> as the EC public key <var>Q</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>secret</var> be the result of applying the field element to
- <a href="#dfn-octet-string">octet string</a> conversion defined in Section ? of <a href="#X9.63">X9.63</a>
- to the output of the ECDH primitive.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> is a value specified in an
- <a href="#dfn-applicable-specification">applicable specification</a> that
- specifies the use of that value with ECDH:
- </dt>
- <dd>
- <p>
- Perform the <a href="#dfn-ecdh-extended-derivation-steps">ECDH key
- derivation steps</a> specified in that specification, passing in
- <var>key</var> and <var>publicKey</var> and resulting in <var>secret</var>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
- </p>
- </dd>
- </dl>
-
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>length</var> is null:</dt>
- <dd>Return <var>secret</var></dd>
- <dt>Otherwise:</dt>
- <dd>
- <dl class="switch">
- <dt>
- If the length of <var>secret</var> in bits is less than
- <var>length</var>:
- </dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>Return the first <var>length</var> bits of <var>secret</var>.</dd>
- </dl>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
-
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> is not empty
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the
- <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
- algorithm over <var>keyData</var>
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is
- not equal to the <code>id-ecPublicKey</code> or <code>id-ecDH</code>
- object identifiers defined in <a href="#RFC5480">RFC 5480</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the <code>algorithm</code>
- AlgorithmIdentifier field of <var>spki</var> is absent,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> that specifies a
- <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>params</var> is equivalent to the <code>secp256r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp384r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp521r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> <code>"P-521"</code>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>namedCurve</var> is not undefined:</dt>
- <dd>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the Elliptic Curve public key identified by
- performing the conversion steps defined in Section 2.2 of <a href="#RFC5480">RFC 5480</a>.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>spki</var>
- and obtaining <var>namedCurve</var> and <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurs while parsing,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithm field of
- <var>privateKeyInfo</var> is not equal to the
- <code>id-ecPublicKey</code> or <code>id-ecDH</code> object identifiers
- defined in <a href="#RFC5480">RFC 5480</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var> is not present,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> that specifies a
- <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose initial value is
- undefined.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>params</var> is equivalent to the <code>secp256r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> to <code>"P-256"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp384r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> to <code>"P-384"</code>.
- </p>
- </dd>
- <dt>
- If <var>params</var> is equivalent to the <code>secp521r1</code>
- object identifier defined in <a href="#RFC5480">RFC 5480</a>:
- </dt>
- <dd>
- <p>
- Set <var>namedCurve</var> to <code>"P-521"</code>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>namedCurve</var> is not undefined:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>ecPrivateKey</var> be the result of performing the
- <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
- algorithm, with <var>data</var> as the <code>privateKey</code> field
- of <var>privateKeyInfo</var>, <var>structure</var> as the ASN.1
- <code>ECPrivateKey</code> structure specified in Section 3 of
- <a href="#RFC5915">RFC 5915</a>, and <var>exactData</var> set to true.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of <var>ecPrivateKey</var> is
- present, and is not an instance of the <code>namedCurve</code> ASN.1
- type defined in <a href="#RFC5480">RFC 5480</a>, or does not contain
- the same object identifier as the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
- of <var>privateKeyInfo</var>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents the Elliptic Curve private key identified by
- performing the conversion steps defined in Section 3 of <a href="#RFC5915">RFC 5915</a> using <var>ecPrivateKey</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
- and obtaining <var>namedCurve</var> and <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"private"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field is present and if <var>usages</var>
- contains an entry which is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"d"</code> field is present and if <var>usages</var> is not
- empty
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is
- to <code>"EC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of <a href="#jwk">JSON Web
- Key</a>, or it does not contain all of the specified <var>usages</var>
- values, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>namedCurve</var> be a string whose value is equal to the
- <code>"crv"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>namedCurve</var> is not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>namedCurve</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <dl class="switch">
- <dt>If the <code>"d"</code> field is present:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- Elliptic Curve private key identified by interpreting
- <var>jwk</var> according to Section 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>Key</var> to <code>"private"</code>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of Section
- 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
- Elliptic Curve public key identified by interpreting
- <var>jwk</var> according to Section 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
- internal slot of <var>Key</var> to <code>"public"</code>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </dd>
- <dt>Otherwise</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and obtaining <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the key value is not a valid point on the Elliptic Curve
- identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new instance of an <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to <var>namedCurve</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a>
- member of <var>normalizedAlgorithm</var> is not a
- <a href="#dfn-NamedCurve">named curve</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>usages</var> is not the empty list,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>extractable</var> is false,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>namedCurve</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>Q</var> be the elliptic curve point on the curve identified
- by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a>
- member of <var>normalizedAlgorithm</var> identified by interpreting
- <var>keyData</var> according to <a href="#X9.62">X9.62</a> Annex A.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object that represents <var>Q</var>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>keyData</var>
- and obtaining <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occured or there are no
- <a href="#dfn-applicable-specifications">applicable
- specifications</a>,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"ECDH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-namedCurve">namedCurve</a>
- attribute of <var>algorithm</var> to equal the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>key</var>
- </p>
- </li>
- </ol>
- </dd>
-
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>key</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> to be
- exported.
- </p>
- </li>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"spki"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 type with the following
- properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier to the OID
- <code>1.3.132.112</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> as follows:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Let <var>keyData</var> be the <a href="#dfn-octet-string">octet string</a> that
- represents the Elliptic Curve public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> according to the encoding rules specified in
- Section 2.2 of <a href="#RFC5480">RFC 5480</a> and using the
- uncompressed form.
- </p>
- <p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp256r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp384r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp521r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- </dl>
- </p>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier <var>namedCurveOid</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> field to <var>keyData</var>
- </p>
- </li>
- </ul>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>version</var> field to <code>0</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to an
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> object identifier to the OID
- <code>1.3.132.112</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>ECParameters</code> ASN.1 type defined in
- <a href="#RFC5480">RFC 5480</a> as follows:
- </p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>,
- <code>"P-384"</code> or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Let <var>keyData</var> be the result of DER-encoding
- an instance of the <code>ECPrivateKey</code> structure defined in
- Section 3 of <a href="#RFC5915">RFC 5915</a> for the Elliptic
- Curve private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> and that conforms to the following:
- </p>
- <ul>
- <li>
- <p>
- The <var>parameters</var> field is present, and is equivalent
- to the <var>parameters</var> field of the
- <var>privateKeyAlgorithm</var> field of this
- <code>PrivateKeyInfo</code> ASN.1 structure.
- </p>
- </li>
- <li>
- <p>
- The <var>publicKey</var> field is present and represents the
- Elliptic Curve public key associated with the Elliptic Curve
- private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- </ul>
- <p>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp256r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp384r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Set <var>parameters</var> to the <var>namedCurve</var> choice
- with value equal to the object identifier
- <code>secp521r1</code> defined in <a href="#RFC5480">RFC
- 5480</a>
- </p>
- </dd>
- </dl>
- </p>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set <var>parameters</var> to the <code>namedCurve</code> choice
- with value equal to the object identifier <var>namedCurveOid</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to <var>keyData</var>.
- </p>
- </li>
- </ul>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to
- <code>"EC"</code>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
- or <code>"P-521"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-256"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-256"</code>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-384"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-384"</code>
- </dd>
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-521"</code>:
- </dt>
- <dd>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <code>"P-521"</code>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>x</code> attribute of <var>jwk</var> according to the
- definition in Section 6.2.1.2 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>y</code> attribute of <var>jwk</var> according to the
- definition in Section 6.2.1.3 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"private"</code>
- </dt>
- <dd>
- <p>
- Set the <code>d</code> attribute of <var>jwk</var> according to the
- definition in Section 6.2.2.1 of <a href="#jwa">JSON Web
- Algorithms</a>.
- </p>
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurve</var> and a new value of <var>jwk</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>crv</code> attribute of <var>jwk</var> to
- <var>namedCurve</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is <code>"raw"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
- of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
- or <code>"P-521"</code>:
- </dt>
- <dd>
- <p>
- Let <var>data</var> be an <a href="#dfn-octet-string">octet string</a> representing the Elliptic Curve
- point <var>Q</var> represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var> according to <a href="#X9.62">X9.62</a> Annex A.
- </p>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and the
- <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>
- and obtaining <var>namedCurve</var> and <var>data</var>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="aes-ctr" class="section">
- <h3>25. AES-CTR</h3>
- <div id="aes-ctr-description" class="section">
- <h4>25.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-CTR"</code> algorithm identifier is used to perform
- encryption and decryption using AES in Counter mode,
- as described in NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>].
- </p>
- </div>
- <div id="aes-ctr-registration" class="section">
- <h4>25.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-CTR"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>encrypt</td>
- <td><a href="#dfn-AesCtrParams">AesCtrParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>decrypt</td>
- <td><a href="#dfn-AesCtrParams">AesCtrParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div id="aes-ctr-params" class="section">
- <h4>25.3. AesCtrParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesCtrParams">AesCtrParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The initial value of the counter block. counter <span class="RFC2119">MUST</span> be 16 bytes
-// (the AES block size). The counter bits are the rightmost length
-// bits of the counter block. The rest of the counter block is for
-// the nonce. The counter bits are incremented using the standard
-// incrementing function specified in NIST SP 800-38A Appendix B.1:
-// the counter bits are interpreted as a big-endian integer and
-// incremented by one.</span>
-required BufferSource <dfn id="dfn-AesCtrParams-counter">counter</dfn>;
-<span class="comment">// The length, in bits, of the rightmost part of the counter block
-// that is incremented.</span>
-[EnforceRange] required octet <dfn id="dfn-AesCtrParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="AesKeyAlgorithm-dictionary" class="section">
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesKeyAlgorithm">AesKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
-<span class="comment">// The length, in bits, of the key.</span>
-required unsigned short <dfn id="dfn-AesKeyAlgorithm-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-keygen-params" class="section">
- <h4>25.5. AesKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesKeyGenParams">AesKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The length, in bits, of the key.</span>
-[EnforceRange] required unsigned short <dfn id="dfn-AesKeyGenParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-derivedkey-params" class="section">
- <h4>25.6. AesDerivedKeyParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesDerivedKeyParams">AesDerivedKeyParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The length, in bits, of the key.</span>
-[EnforceRange] required unsigned short <dfn id="dfn-AesDerivedKeyParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
-
- <div id="aes-ctr-operations" class="section">
- <h4>25.7. Operations</h4>
- <dl>
- <dt>Encrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCtrParams-counter">counter</a> member of
- <var>normalizedAlgorithm</var> does not have length 16
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesCtrParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is zero or is greater
- than 128,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be the result of performing the CTR Encryption
- operation described in Section 6.5 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCtrParams-counter">counter</a> member of
- <var>normalizedAlgorithm</var> as the initial value of the counter block, the
- <a href="#dfn-AesCtrParams-length">length</a> member of
- <var>normalizedAlgorithm</var> as the input parameter <var>m</var> to the
- standard counter block incrementing function defined in Appendix B.1 of NIST SP
- 800-38A [<a href="#SP800-38A">SP800-38A</a>] and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>plaintext</var></a> as the input plaintext.
- </p>
- </li>
- <li>
- <p>
- Return <var>ciphertext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Decrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCtrParams-counter">counter</a> member of
- <var>normalizedAlgorithm</var> does not have length 16
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesCtrParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is zero or is greater
- than 128,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>plaintext</var> be the result of performing the CTR Decryption
- operation described in Section 6.5 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCtrParams-counter">counter</a> member of
- <var>normalizedAlgorithm</var> as the initial value of the counter block, the
- <a href="#dfn-AesCtrParams-length">length</a> member of
- <var>normalizedAlgorithm</var> as the input parameter <var>m</var> to the
- standard counter block incrementing function defined in Appendix B.1 of NIST SP
- 800-38A [<a href="#SP800-38A">SP800-38A</a>] and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>ciphertext</var></a> as the input ciphertext.
- </p>
- </li>
- <li>
- <p>
- Return <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not equal to one of
- 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
-
- <li>
- <p>
- Generate an AES key of length
- equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CTR"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code> object representing an AES key with
- value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CTR"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128CTR"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192CTR"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256CTR"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="aes-cbc" class="section">
- <h3>26. AES-CBC</h3>
- <div id="aes-cbc-description" class="section">
- <h4>26.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-CBC"</code> algorithm identifier is used to perform
- encryption and decryption using AES in Cipher Block Chaining mode,
- as described in NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>].
- </p>
- <p>
- When operating in CBC mode, messages that are not exact multiples
- of the AES block size (16 bytes) can be padded under a variety of
- padding schemes. In the Web Crypto API, the only padding mode that
- is supported is that of PKCS#7, as described by
- Section 10.3, step 2, of RFC 2315 [<a href="#RFC2315">RFC2315</a>].
- </p>
- </div>
- <div id="aes-cbc-registration" class="section">
- <h4>26.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-CBC"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>encrypt</td>
- <td><a href="#dfn-AesCbcParams">AesCbcParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>decrypt</td>
- <td><a href="#dfn-AesCbcParams">AesCbcParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="aes-cbc-params" class="section">
- <h4>26.3. AesCbcParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesCbcParams">AesCbcParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The initialization vector. <span class="RFC2119">MUST</span> be 16 bytes.</span>
-required BufferSource <dfn id="dfn-AesCbcParams-iv">iv</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-cbc-operations" class="section">
- <h4>26.4. Operations</h4>
- <dl>
- <dt>Encrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCbcParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> does not have length 16
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>paddedPlaintext</var> be the result of adding padding octets to
- the <a href="#concept-contents-of-arraybuffer">contents of <var>ciphertext</var></a>
- according to the procedure defined in Section 10.3
- of RFC 2315 [<a href="#RFC2315">RFC2315</a>], step 2, with a value of
- <var>k</var> of 16.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be the result of performing the CBC Encryption
- operation described in Section 6.2 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCbcParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter and <var>paddedPlaintext</var>
- as the input plaintext.
- </p>
- </li>
- <li>
- <p>
- Return <var>ciphertext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Decrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCbcParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> does not have length 16
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>paddedPlaintext</var> be the result of performing the CBC Decryption
- operation described in Section 6.2 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCbcParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>ciphertext</var></a> as the input ciphertext.
- </p>
- </li>
- <li>
- <p>
- Let <var>p</var> be the value of the last octet of <var>paddedPlaintext</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>p</var> is zero or greater than 16, or if any of the last <var>p</var>
- octets of <var>paddedPlaintext</var> have a value which is not <var>p</var>,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>plaintext</var> be the result of removing <var>p</var> octets from
- the end of <var>paddedPlaintext</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not equal to one of
- 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
-
- <li>
- <p>
- Generate an AES key of length
- equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CBC"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- to <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128CBC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192CBC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256CBC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
- object representing an AES key with value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CBC"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128CBC"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192CBC"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256CBC"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="aes-cmac" class="section">
- <h3>27. AES-CMAC</h3>
- <div id="aes-cmac-description" class="section">
- <h4>27.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-CMAC"</code> algorithm identifier is used to perform
- message authentication using AES with a cipher-based MAC, as
- described in NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>].
- </p>
- </div>
- <div id="aes-cmac-registration" class="section">
- <h4>27.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-CMAC"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>sign</td>
- <td><a href="#dfn-AesCmacParams">AesCmacParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>verify</td>
- <td><a href="#dfn-AesCmacParams">AesCmacParams</a></td>
- <td>boolean</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="aes-cmac-params" class="section">
- <h4>27.3. AesCmacParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesCmacParams">AesCmacParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The length, in bits, of the MAC.</span>
-[EnforceRange] required unsigned short <dfn id="dfn-AesCmacParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-cmac-operations" class="section">
- <h4>27.4. Operations</h4>
- <dl>
- <dt>Sign</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>length</var> equal the <a href="#dfn-AesCmacParams-length">length</a>
- member of <var>normalizedAlgorithm</var>, if present, and 128 otherwise.
- </p>
- </li>
- <li>
- <p>
- If <var>length</var> is zero or greater than 128,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>mac</var> be the result of performing the MAC Generation
- operation described in Section 6.2 of
- NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>] using AES as the block
- cipher, <var>length</var> as the value of the MAC length parameter,
- <var>Tlen</var>, and <var>message</var> as the message, <var>M</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>mac</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Verify</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>length</var> equal the <a href="#dfn-AesCmacParams-length">length</a>
- member of <var>normalizedAlgorithm</var>, if present, and 128 otherwise.
- </p>
- </li>
- <li>
- <p>
- If <var>length</var> is zero or greater than 128,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>output</var> be the result of performing the MAC Verification
- operation described in Section 6.3 of
- NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>] using AES as the block
- cipher, <var>length</var> as the value of the MAC length parameter,
- <var>Tlen</var>, <var>message</var> as the message, <var>M</var> and
- <var>signature</var> as the received MAC, <var>T'</var>.
- </p>
- </li>
- <li>
- <p>
- Return true if <var>output</var> is VALID and false otherwise.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not
- <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not equal to one of
- 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate an AES key of length
- equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CMAC"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- to <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128CMAC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192CMAC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256CMAC"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
- object representing an AES key with value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CMAC"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128CMAC"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192CMAC"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256CMAC"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
- <div id="aes-gcm" class="section">
- <h3>28. AES-GCM</h3>
- <div id="aes-gcm-description" class="section">
- <h4>28.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-GCM"</code> algorithm identifier is used to perform
- authenticated encryption and decryption using AES in Galois/Counter Mode mode,
- as described in NIST SP 800-38D [<a href="#SP800-38D">SP800-38D</a>].
- </p>
- </div>
- <div id="aes-gcm-registration" class="section">
- <h4>28.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-GCM"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>encrypt</td>
- <td><a href="#dfn-AesGcmParams">AesGcmParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>decrypt</td>
- <td><a href="#dfn-AesGcmParams">AesGcmParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="aes-gcm-params" class="section">
- <h4>28.3. AesGcmParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesGcmParams">AesGcmParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The initialization vector to use. May be up to 2^64-1 bytes long.</span>
-required BufferSource <dfn id="dfn-AesGcmParams-iv">iv</dfn>;
-<span class="comment">// The additional authentication data to include.</span>
-BufferSource <dfn id="dfn-AesGcmParams-additionalData">additionalData</dfn>;
-<span class="comment">// The desired length of the authentication tag. May be 0 - 128.</span>
-[EnforceRange] octet <dfn id="dfn-AesGcmParams-tagLength">tagLength</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-gcm-operations" class="section">
- <h4>28.4. Operations</h4>
- <dl>
- <dt>Encrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>plaintext</var> has a length greater than 2^39 - 256
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesGcmParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> has a length greater than 2^64 - 1
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member
- of <var>normalizedAlgorithm</var> is present and has a length
- greater than 2^64 - 1 bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var> is not present:</dt>
- <dd>Let <var>tagLength</var> be 128.</dd>
- <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var> is one of 32, 64, 96, 104, 112, 120 or 128:</dt>
- <dd>Let <var>tagLength</var> be equal to the
- <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var></dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>additionalData</var> be <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member of
- <var>normalizedAlgorithm</var> if present or the empty octet
- string otherwise.
- </p>
- </li>
- <li>
- <p>
- Let <var>C</var> and <var>T</var> be the outputs that result from performing
- the Authenticated Encryption Function described in Section 7.1 of NIST SP
- 800-38D [<a href="#SP800-38D">SP800-38D</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter, <a href="#concept-contents-of-arraybuffer">the contents of
- <var>additionalData</var></a> as the <var>A</var> input parameter,
- <var>tagLength</var> as the <var>t</var> pre-requisite and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>plaintext</var></a> as the input plaintext.
- </p>
- </li>
- <li>
- <p>
- Return a new ArrayBuffer containing <var>C</var> | <var>T</var>
- where '|' denotes concatenation.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Decrypt</dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var> is not present:</dt>
- <dd>Let <var>tagLength</var> be 128.</dd>
- <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var> is one of 32, 64, 96, 104, 112, 120 or 128:</dt>
- <dd>Let <var>tagLength</var> be equal to the
- <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
- <var>normalizedAlgorithm</var></dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If <var>plaintext</var> has a length less than <var>tagLength</var> bits,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesGcmParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> has a length greater than 2^64 - 1
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member
- of <var>normalizedAlgorithm</var> is present and has a length
- greater than 2^64 - 1
- bytes,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>tag</var> be the last <var>tagLength</var> bits of
- <var>ciphertext</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>actualCiphertext</var> be the result of removing the last <var>tagLength</var> bits
- from <var>ciphertext</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>additionalData</var> be <a href="#concept-contents-of-arraybuffer">the contents</a> of the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member of
- <var>normalizedAlgorithm</var> if present or the empty octet
- string otherwise.
- </p>
- </li>
- <li>
- <p>
- Perform the Authenticated Decryption Function described in Section 7.2 of NIST
- SP 800-38D [<a href="#SP800-38D">SP800-38D</a>] using AES as the block cipher,
- <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter, <a href="#concept-contents-of-arraybuffer">the contents of
- <var>additionalData</var></a> as the <var>A</var> input parameter,
- <var>tagLength</var> as the <var>t</var> pre-requisite, <a href="#concept-contents-of-arraybuffer">the contents of
- <var>actualCiphertext</var></a> as the input ciphertext, <var>C</var> and <a href="#concept-contents-of-arraybuffer">the contents of <var>tag</var></a> as
- the authentication tag, <var>T</var>.
- </p>
- <dl class="switch">
- <dt>If the result of the algorithm is the indication of inauthenticity,
- "<var>FAIL</var>":</dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>
- </dd>
- <dt>Otherwise:</dt>
- <dd>Let <var>plaintext</var> be the output <var>P</var> of the Authenticated
- Decryption Function.</dd>
- </dl>
- </li>
- <li>
- <p>
- Return a new ArrayBuffer containing <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not equal to one of
- 128, 192 or 256,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
-
- <li>
- <p>
- Generate an AES key of length
- equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-GCM"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128GCM"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192GCM"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256GCM"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
- object representing an AES key with value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-GCM"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128GCM"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192GCM"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256GCM"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="aes-cfb" class="section">
- <h3>29. AES-CFB</h3>
- <div id="aes-cfb-description" class="section">
- <h4>29.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-CFB-8"</code> algorithm identifier is used to perform
- encryption and decryption using AES in Cipher Feedback mode, specifically CFB-8,
- as described in Section 6.3 of NIST SP 800-38A
- [<a href="#SP800-38A">SP800-38A</a>].
- </p>
- </div>
- <div id="aes-cfb-registration" class="section">
- <h4>29.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-CFB-8"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>encrypt</td>
- <td><a href="#dfn-AesCfbParams">AesCfbParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>decrypt</td>
- <td><a href="#dfn-AesCfbParams">AesCfbParams</a></td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="aes-cfb-params" class="section">
- <h4>29.3. AesCfbParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-AesCfbParams">AesCfbParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The initialization vector. <span class="RFC2119">MUST</span> be 16 bytes.</span>
-required BufferSource <dfn id="dfn-AesCfbParams-iv">iv</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="aes-cfb-operations" class="section">
- <h4>29.4. Operations</h4>
- <dl>
- <dt>Encrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCfbParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> does not have length 16 bytes, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be the result of performing the CFB Encryption
- operation described in Section 6.3 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCfbParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter, the value 8 as the input parameter
- <var>s</var>, and <a href="#concept-contents-of-arraybuffer">the contents
- of<var>plaintext</var></a> as the input plaintext.
- </p>
- </li>
- <li>
- <p>
- Return <var>ciphertext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Decrypt</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesCfbParams-iv">iv</a> member of
- <var>normalizedAlgorithm</var> does not have length 16 bytes, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>plaintext</var> be the result of performing the CFB Decryption
- operation described in Section 6.3 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCfbParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
- the <var>IV</var> input parameter, the the value 8 as the input parameter
- <var>s</var>, and <a href="#concept-contents-of-arraybuffer">the contents of
- <var>ciphertext</var></a> as the input ciphertext.
- </p>
- </li>
- <li>
- <p>
- Return <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not one of
- <code>"encrypt"</code>, <code>"decrypt"</code>, <code>"wrapKey"</code> or
- <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not equal to one of 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate an AES key of length equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CFB-8"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- one of <code>"encrypt"</code>, <code>"decrypt"</code>,
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
-
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128CFB8"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192CFB8"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256CFB8"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
- object representing an AES key with value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-CFB-8"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to the <a href="#concept-normalized-usages">normalized
- value</a> of <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128CFB8"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192CFB8"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256CFB8"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> property of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> property of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="aes-kw" class="section">
- <h3>30. AES-KW</h3>
- <div id="aes-kw-description" class="section">
- <h4>30.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"AES-KW"</code> algorithm identifier is used to perform
- key wrapping using AES, as
- described in [<a href="#rfc3394">RFC3394</a>].
- </p>
- </div>
- <div id="aes-kw-registration" class="section">
- <h4>30.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"AES-KW"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>wrapKey</td>
- <td>None</td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>unwrapKey</td>
- <td>None</td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="aes-kw-operations" class="section">
- <h4>30.3. Operations</h4>
- <dl>
- <dt>Wrap Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>plaintext</var> is not a multiple of 64 bits in length,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>ciphertext</var> be the result of performing the Key Wrap
- operation described in Section 2.2.1 of [<a href="#rfc3394">RFC3394</a>]
- with <var>plaintext</var> as the plaintext to be wrapped and using the default
- Initial Value defined in Section 2.2.3.1 of the same document.
- </p>
- </li>
- <li>
- <p>
- Return <var>ciphertext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Unwrap Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>plaintext</var> be the result of performing the Key Unwrap
- operation described in Section 2.2.2 of [<a href="#rfc3394">RFC3394</a>] with
- <var>ciphertext</var> as the input ciphertext and using the default Initial
- Value defined in Section 2.2.3.1 of the same document.
- </p>
- </li>
- <li>
- <p>
- If the Key Unwrap operation returns an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return <var>plaintext</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not one of
- <code>"wrapKey"</code> or <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-AesKeyGenParams-length">length</a> property of
- <var>normalizedAlgorithm</var> is not equal to one of 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated AES key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-KW"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to equal the
- <a href="#dfn-AesKeyGenParams-length">length</a> property of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- one of <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
-
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the length in bits of <var>data</var> is not 128, 192 or 256
-
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>data</var> has length 128 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A128KW"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 192 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A192KW"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>If <var>data</var> has length 256 bits:</dt>
- <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
- not <code>"A256KW"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"enc"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>. </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
- object representing an AES key with value <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"AES-KW"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to the length, in bits, of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 128:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A128KW"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 192:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A192KW"</code>.</dd>
- <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
- <var>key</var> is 256:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"A256KW"</code>.</dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="hmac" class="section">
- <h3>31. HMAC</h3>
- <div id="hmac-description" class="section">
- <h4>31.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>HMAC</code> algorithm calculates and verifies hash-based message
- authentication codes according to [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>]
- using the SHA hash functions defined in this specification.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with HMAC. Such specifications
- must define the digest operation for the additional hash algorithms and
- <dfn id="dfn-hmac-extended-import-steps">key import steps</dfn> and
- <dfn id="dfn-hmac-extended-export-steps">key export steps</dfn> for HMAC.
- </p>
-
- </div>
- <div id="hmac-registration" class="section">
- <h4>31.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"HMAC"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>sign</td>
- <td>None</td>
- <td>ArrayBuffer</td>
- </tr>
- <tr>
- <td>verify</td>
- <td>None</td>
- <td>boolean</td>
- </tr>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-HmacKeyGenParams">HmacKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-HmacImportParams">HmacImportParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- <tr>
- <td>get key length</td>
- <td><a href="#dfn-HmacImportParams">HmacImportParams</a></td>
- <td>Integer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="hmac-importparams" class="section">
- <h4>31.3. HmacImportParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-HmacImportParams">HmacImportParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The inner hash function to use.</span>
-<a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HmacImportParams-hash">hash</dfn>;
-<span class="comment">// The length (in bits) of the key.</span>
-[EnforceRange] unsigned long <dfn id="dfn-HmacImportParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="HmacKeyAlgorithm-dictionary" class="section">
- <h4>31.4. HmacKeyAlgorithm dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
-<span class="comment">// The inner hash function to use.</span>
-required KeyAlgorithm <dfn id="dfn-HmacKeyAlgorithm-hash">hash</dfn>;
-<span class="comment">// The length (in bits) of the key.</span>
-required unsigned long <dfn id="dfn-HmacKeyAlgorithm-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="hmac-keygen-params" class="section">
- <h4>31.5. HmacKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-HmacKeyGenParams">HmacKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The inner hash function to use.</span>
-required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HmacKeyGenParams-hash">hash</dfn>;
-<span class="comment">// The length (in bits) of the key to generate. If unspecified, the
-// recommended length will be used, which is the size of the associated hash function's block
-// size.</span>
-[EnforceRange] unsigned long <dfn id="dfn-HmacKeyGenParams-length">length</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="hmac-operations" class="section">
- <h4>31.6. Operations</h4>
- <dl>
- <dt>Sign</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>mac</var> be the result of performing the MAC Generation operation
- described in Section 4 of [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using
- the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
- internal slot of <var>key</var>, the hash function identified by the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> and <var>message</var> as the input data <var>text</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>mac</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Verify</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>mac</var> be the result of performing the MAC Generation operation
- described in Section 4 of [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using
- the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
- internal slot of <var>key</var>, the hash function identified by the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var> and <var>message</var> as the input data <var>text</var>.
- </p>
- </li>
- <li>
- <p>
- Return true if <var>mac</var> is equal to <var>signature</var> and false
- otherwise.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains any entry which is not <code>"sign"</code> or
- <code>"verify"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacKeyGenParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is not present:
- </dt>
- <dd>
- Let <var>length</var> be the block size in bits of the hash function
- identified by the <a href="#dfn-HmacKeyGenParams-hash">hash</a> member
- of <var>normalizedAlgorithm</var>.
- </dd>
- <dt>
- Otherwise, if the <a href="#dfn-HmacKeyGenParams-length">length</a>
- member of <var>normalizedAlgorithm</var> is non-zero:
- </dt>
- <dd>
- Let <var>length</var> be equal to the
- <a href="#dfn-HmacKeyGenParams-length">length</a>
- member of <var>normalizedAlgorithm</var>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- </dl>
- </li>
-
- <li>
- <p>
- Generate a key of length <var>length</var> bits.
- </p>
- </li>
- <li>
- <p>
- If the key generation step fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new
- <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
- generated key.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"HMAC"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be a new
- <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> to equal the <a href="#dfn-Algorithm-name">name</a>
- member of the <a href="#dfn-HmacKeyGenParams-hash">hash</a>
- member of <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute
- of <var>algorithm</var> to <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to be <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <p>
- If <var>usages</var> contains an entry which is not
- <code>"sign"</code> or <code>"verify"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var> is present:
- </dt>
- <dd>
- Set <var>hash</var> to equal the <a href="#dfn-HmacImportParams-hash">hash</a>
- member of <var>normalizedAlgorithm</var>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary represented by <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"kty"</code> field of <var>jwk</var> is not
- <code>"oct"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>jwk</var> does not meet the requirements of
- Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
- <code>"k"</code> field of <var>jwk</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var> is present:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Set the <var>hash</var> to equal the <a href="#dfn-HmacImportParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is
- <code>"SHA-1"</code>:
- </dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present
- and is not <code>"HS1"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is
- <code>"SHA-256"</code>:
- </dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present
- and is not <code>"HS256"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is
- <code>"SHA-384"</code>:
- </dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present
- and is not <code>"HS384"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is
- <code>"SHA-512"</code>:
- </dt>
- <dd>
- If the <code>"alg"</code> field of <var>jwk</var> is present
- and is not <code>"HS512"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- Otherwise, if the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is defined in
- <a href="#dfn-applicable-specifications">another applicable
- specification</a>:
- </dt>
- <dd>
- Perform any <a href="#dfn-hmac-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and <var>hash</var>
- and obtaining <var>hash</var>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <code>alg</code> field of <var>jwk</var> is not present,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is
- <code>"HS1"</code>:
- </dt>
- <dd>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> to <code>"SHA-1"</code>.
- </dd>
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is
- to <code>"HS256"</code>:
- </dt>
- <dd>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> to <code>"SHA-256"</code>.
- </dd>
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is
- <code>"HS384"</code>:
- </dt>
- <dd>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> to <code>"SHA-384"</code>.
- </dd>
- <dt>
- If the <code>"alg"</code> field of <var>jwk</var> is
- <code>"HS512"</code>:
- </dt>
- <dd>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> to <code>"SHA-512"</code>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- Perform any <a href="#dfn-hmac-extended-import-steps">key
- import steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var>, <var>jwk</var>
- and undefined
- and obtaining <var>hash</var>.
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If the <code>"use"</code> field of <var>jwk</var> is present, and is
- not <code>"sign"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
- is invalid according to the requirements of
- <a href="#jwk">JSON Web Key</a> or
- does not contain all of the specified <var>usages</var> values,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>"ext"</code> field of <var>jwk</var> is present and
- has the value false and <var>extractable</var> is true,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>length</var> be equivalent to the length, in octets, of
- <var>data</var>, multiplied by 8.
- </p>
- </li>
- <li>
- <p>
- If <var>length</var> is zero
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacImportParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is present:
- </dt>
- <dd>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacImportParams-length">length</a> member of
- <var>normalizedAlgorithm</var> is greater than <var>length</var>:
- </dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- If the <a href="#dfn-HmacImportParams-length">length</a> member of
- <var>normalizedAlgorithm</var>, is less than or equal to
- <var>length</var> minus eight:
- </dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-DataError"><code>DataError</code></a>.
- </dd>
- <dt>
- Otherwise:
- </dt>
- <dd>
- Set <var>length</var> equal to the <a href="#dfn-HmacImportParams-length">
- length</a> member of <var>normalizedAlgorithm</var>.
- </dd>
- </dl>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
- object representing an HMAC key with the first <var>length</var>
- bits of <var>data</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"HMAC"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-HmacKeyAlgorithm-length">length</a> attribute of
- <var>algorithm</var> to <var>length</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of
- <var>algorithm</var> to <var>hash</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>If <var>format</var> is <code>"raw"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <code>kty</code> attribute of <var>jwk</var> to the
- string <code>"oct"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>k</code> attribute of <var>jwk</var> to be a string
- containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>hash</var> be the
- <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of
- <var>algorithm</var>.
- </p>
- </li>
-
- <li>
- <dl class="switch">
- <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> is <code>"SHA-1"</code>:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"HS1"</code>.</dd>
- <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> is <code>"SHA-256"</code>:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"HS256"</code>.</dd>
- <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> is <code>"SHA-384"</code>:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"HS384"</code>.</dd>
- <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>hash</var> is <code>"SHA-512"</code>:</dt>
- <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
- the string <code>"HS512"</code>.</dd>
- <dt>
- Otherwise, the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
- of <var>hash</var> is defined in
- <a href="#dfn-applicable-specifications">another applicable
- specification</a>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- Perform any <a href="#dfn-hmac-extended-export-steps">key
- export steps</a> defined by
- <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>format</var> and <var>key</var>
- and obtaining <var>alg</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>alg</code> attribute of <var>jwk</var> to
- <var>alg</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
- <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of converting <var>jwk</var>
- to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </p>
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get key length</dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-HmacIMportParams-length">length</a> member of
- <var>normalizedDerivedKeyAlgorithm</var> is not present:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the <a href="#dfn-HmacImportParams-hash">hash</a> member
- of <var>normalizedDerivedKeyAlgorithm</var> is not present,
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>length</var> be the block size in bytes of the hash function
- identified by the <a href="#dfn-HmacImportParams-hash">hash</a> member
- of <var>normalizedDerivedKeyAlgorithm</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- Otherwise, if the <a href="#dfn-HmacImportParams-length">length</a>
- member of <var>normalizedDerivedKeyAlgorithm</var> is non-zero:
- </dt>
- <dd>
- Let <var>length</var> be equal to the
- <a href="#dfn-HmacImportParams-length">length</a>
- member of <var>normalizedDerivedKeyAlgorithm</var>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>length</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
- <div id="dh" class="section">
- <h3>32. Diffie-Hellman</h3>
- <div id="dh-description" class="section">
- <h4>32.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- This describes using Diffie-Hellman for key generation and key agreement, as specified
- by <a href="#PKCS3">PKCS #3</a>.
- </p>
- </div>
- <div id="dh-registration" class="section">
- <h4>32.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"DH"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>generateKey</td>
- <td><a href="#dfn-DhKeyGenParams">DhKeyGenParams</a></td>
- <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
- </tr>
- <tr>
- <td>deriveBits</td>
- <td><a href="#dfn-DhKeyDeriveParams">DhKeyDeriveParams</a></td>
- <td><a href="#dfn-octet-string">Octet string</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td><a href="#dfn-DhImportKeyParams">DhImportKeyParams</a></td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>exportKey</td>
- <td>None</td>
- <td>object</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="dh-DhKeyGenParams" class="section">
- <h4>32.3. DhKeyGenParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-DhKeyGenParams">DhKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The prime p.</span>
-required BigInteger <dfn id="dfn-DhKeyGenParams-prime">prime</dfn>;
-<span class="comment">// The base g.</span>
-required BigInteger <dfn id="dfn-DhKeyGenParams-generator">generator</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="dh-DhKeyAlgorithm" class="section">
- <h4>32.4. DhKeyAlgorithm dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-DhKeyAlgorithm">DhKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
-<span class="comment">// The prime p.</span>
-required BigInteger <dfn id="dfn-DhKeyAlgorithm-prime">prime</dfn>;
-<span class="comment">// The base g.</span>
-required BigInteger <dfn id="dfn-DhKeyAlgorithm-generator">generator</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="dh-DhKeyDeriveParams" class="section">
- <h4>32.5. DhKeyDeriveParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-DhKeyDeriveParams">DhKeyDeriveParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The peer's public value.</span>
-required <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-DhKeyDeriveParams-public">public</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="dh-DhImportKeyParams" class="section">
- <h4>32.6. DhImportKeyParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-DhImportKeyParams">DhImportKeyParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The prime p.</span>
-required BigInteger <dfn id="dfn-DhImportKeyParams-prime">prime</dfn>;
-<span class="comment">// The base g.</span>
-required BigInteger <dfn id="dfn-DhImportKeyParams-generator">generator</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="dh-operations" class="section">
- <h4>32.7. Operations</h4>
- <dl>
- <dt>Generate Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value which is not
- one of <code>"deriveKey"</code> or <code>"deriveBits"</code>,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate a Diffie-Hellman key pair, as defined in Section 7 of
- [<a href="#PKCS3">PKCS #3</a>], with prime, <var>p</var>, and base,
- <var>g</var>, as specified in the
- <a href="#dfn-DhKeyGenParams-prime">prime</a> and
- <a href="#dfn-DhKeyGenParams-generator">generator</a> properties of
- <var>normalizedAlgorithm</var>, respectively.
- </p>
- </li>
- <li>
- <p>
- If performing the operation results in an error,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-Algorithm-name">name</a> member of
- <var>algorithm</var> to <code>"DH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-DhKeyGenParams-prime">prime</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
- attribute of <var>algorithm</var> to equal the
- <a href="#dfn-DhKeyGenParams-generator">generator</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the public key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> to <code>"public"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>publicKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>publicKey</var> to true.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>publicKey</var> to be the empty list.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the private key of the generated key pair.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>privateKey</var> to <code>"private"</code>
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>privateKey</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>privateKey</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>privateKey</var> to be <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
- dictionary.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
- of <var>result</var> to be <var>publicKey</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
- of <var>result</var> to be <var>privateKey</var>.
- </p>
- </li>
- <li>
- <p>
- Return the result of converting <var>result</var> to an ECMAScript Object, as
- defined by [<a href="#WebIDL">WEBIDL</a>].
- </p>
- </li>
- </ol>
- </dd>
- <dt>Derive Bits</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>publicKey</var> be the
- <a href="#dfn-DhKeyDeriveParams-public">public</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>publicKey</var> is not <code>"DH"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>publicKey</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>publicKey</var> is not equal to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of the
- [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>publicKey</var> is not equal to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
- <var>key</var>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Perform the Diffie-Hellman Phase II algorithm as specified in Section 8 of [<a href="#PKCS3">PKCS #3</a>] with <var>key</var> as the DH private value
- <var>x</var> and the Diffie-Hellman public value represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of the <a href="#dfn-DhKeyDeriveParams-public">public</a> member of
- <var>normalizedAlgorithm</var> as the other's public value <var>PV'</var>.
- </p>
- <dl class="switch">
- <dt>If performing the operation results in an error:</dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- Let <var>secret</var> be the output of the DH Phase II, <var>SK</var>.
- </dd>
- </dl>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If the length of <var>secret</var> in bits is less than
- <var>length</var>:
- </dt>
- <dd>
- <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </dd>
- <dt>Otherwise:</dt>
- <dd>Return the first <var>length</var> bits of <var>secret</var>.</dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Import Key</dt>
- <dd>
- <dl class="switch">
- <dt>
- If <var>format</var> is <code>"raw"</code>:
- </dt>
- <dd>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- Raw import of private values is presently not supported.
- </p>
- </div>
- <ol>
- <li>
- <p>
- If <var>usages</var> is not empty
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>extractable</var> is false,
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>PV</var> be the integer which results from interpreting the
- octets of <var>keyData</var> as an unsigned big integer with most
- significant octet first.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing a Diffie-Hellman public key with public value <var>PV</var>
- and with prime, <var>p</var> and base, <var>g</var> equal to the <a href="#dfn-DhImportKeyParams-prime">prime</a> and <a href="#dfn-DhImportKeyParams-generator">generator</a> properties of
- <var>normalizedAlgorithm</var> respectively.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"public"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-Algorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"DH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
- <var>algorithm</var> to equal the <a href="#dfn-DhImportKeyParams-prime">prime</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
- <var>algorithm</var> to equal the <a href="#dfn-DhImportKeyParams-generator">generator</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is <code>"spki"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> is not empty
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>spki</var> be the result of running the <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a> algorithm
- over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is not
- equivalent to the <code>dhKeyAgreement</code> OID defined in Section 9 of
- [<a href="#PKCS3">PKCS #3</a>], then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the <code>algorithm</code>
- AlgorithmIdentifier field of <var>spki</var> is absent, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the <code>DHParameter</code>
- ASN.1 type defined in Section 9 of <a href="#PKCS3">PKCS #3</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the Diffie-Hellman public key obtained by parsing the
- <code>subjectPublicKey</code> field of <var>spki</var> as an ASN.1
- INTEGER.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"public"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-Algorithm-name">name</a> member of
- <var>algorithm</var> to <code>"DH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
- <var>algorithm</var> to a new <code>BigInteger</code> equal to the
- <a href="#dfn-octet-string">octet string</a> encoding of the <code>prime</code> field of
- <var>params</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
- <var>algorithm</var> to a new <code>BigInteger</code> equal to the
- <a href="#dfn-octet-string">octet string</a> encoding of the <code>base</code> field of
- <var>params</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is <code>"pkcs8"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value which is not one of
- <code>"deriveKey"</code> or <code>"deriveBits"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>privateKeyInfo</var> be the result of running the
- <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
- algorithm over <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>algorithm</code> object identifier field of the
- <code>algorithm</code> AlgorithmIdentifier field of
- <var>privateKeyInfo</var> is not equivalent to the
- <code>dhKeyAgreement</code> OID defined in Section 9 of [<a href="#PKCS3">PKCS #3</a>], then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field of
- <var>privateKeyInfo</var> is absent, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>params</var> be the <code>parameters</code> field of the
- <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field of
- <var>privateKeyInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If <var>params</var> is not an instance of the <code>DHParameter</code>
- ASN.1 type defined in Section 9 of <a href="#PKCS3">PKCS #3</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
- </p>
- </li>
- <li>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the Diffie-Hellman private key obtained by parsing the
- <code>privateKey</code> field of <var>privateKeyInfo</var> as an ASN.1
- INTEGER.
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"private"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-Algorithm-name">name</a> member of
- <var>algorithm</var> to <code>"DH"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
- <var>algorithm</var> to a new <code>BigInteger</code> equal to the
- <a href="#dfn-octet-string">octet string</a> encoding of the <code>prime</code> field of
- <var>params</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
- <var>algorithm</var> to a new <code>BigInteger</code> equal to the
- <a href="#dfn-octet-string">octet string</a> encoding of the <code>base</code> field of
- <var>params</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </dd>
- <dt>Export Key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is <code>"raw"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"public"</code>:
- </dt>
- <dd>
- Let <var>data</var> be the Public Value, <var>PV</var>, associated
- with <var>key</var> as specified in Section 7 of [<a href="#PKCS3">PKCS #3</a>].
- </dd>
- <dt>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is <code>"private"</code>:
- </dt>
- <dd>
- Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> that represents the private
- value <var>x</var> associated with <var>key</var> as a big integer,
- most significant octet first.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is <code>"spki"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithmIdentifier</var> field to an
- <code>AlgorithmIdentifier</code> ASN.1 structure with the
- following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the
- <code>dhKeyAgreement</code> OID defined in Section 9 of <a href="#PKCS3">PKCS #3</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>DHParams</code> ASN.1 structure defined in Section 9 of
- <a href="#PKCS3">PKCS #3</a> with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>prime</var> field to an ASN.1 INTEGER that is
- equivalent to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>base</var> field to an ASN.1 INTEGER that is
- equivalent to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>subjectPublicKey</var> to an ASN.1 INTEGER that
- corresponds to the Diffie-Hellman public value represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
- <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>
- If <var>format</var> is <code>"pkcs8"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
- of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
- ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
- with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>privateKeyAlgorithm</var> field to a
- <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 structure with
- the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>algorithm</var> field to the
- <code>dhKeyAgreement</code> OID defined in Section 9 of <a href="#PKCS3">PKCS #3</a>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>parameters</var> field to an instance of the
- <code>DHParams</code> ASN.1 structure defined in Section 9 of
- <a href="#PKCS3">PKCS #3</a> with the following properties:
- </p>
- <ul>
- <li>
- <p>
- Set the <var>prime</var> field to an ASN.1 INTEGER that is
- equivalent to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
- the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- <li>
- <p>
- Set the <var>base</var> field to an ASN.1 INTEGER that is
- equivalent to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
- attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
- internal slot of <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Set the <var>privateKey</var> field to an ASN.1 INTEGER that
- corresponds to the Diffie-Hellman private value represented by
- [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
- of <var>key</var>.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- Let <var>result</var> be a new <code>ArrayBuffer</code> containing
- <var>data</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
- <div id="sha" class="section">
- <h3>33. SHA</h3>
- <div id="sha-description" class="section">
- <h4>33.1. Description</h4>
- <p>
- This describes the SHA-1 and SHA-2 families, as specified by
- [<a href="#FIPS180-4">FIPS PUB 180-4</a>].
- </p>
- </div>
- <div id="sha-registration" class="section">
- <h4>33.2. Registration</h4>
- <p>
- The following algorithms are added as <a href="#recognized-algorithm-name">
- recognized algorithm names</a>:
- </p>
- <dl>
- <dt id="alg-sha-1"><code>"SHA-1"</code></dt>
- <dd>The SHA-1 algorithm as specified in Section 6.1</dd>
- <dt id="alg-sha-256"><code>"SHA-256"</code></dt>
- <dd>The SHA-256 algorithm as specified in Section 6.2</dd>
- <dt id="alg-sha-384"><code>"SHA-384"</code></dt>
- <dd>The SHA-384 algorithm as specified in Section 6.5</dd>
- <dt id="alg-sha-512"><code>"SHA-512"</code></dt>
- <dd>The SHA-512 algorithm as specified in Section 6.4</dd>
- </dl>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>digest</td>
- <td>None</td>
- <td>ArrayBuffer</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="sha-operations" class="section">
- <h4>33.3. Operations</h4>
- <dl>
- <dt>Digest</dt>
- <dd>
- <ol>
- <li>
- <dl class="switch">
- <dt>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is a cases-sensitive string match for
- <code>"SHA-1"</code>:
- </dt>
- <dd>
- Let <var>result</var> be the result of performing the SHA-1 hash function
- defined in Section 6.1 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
- <var>message</var> as the input message, <var>M</var>.
- </dd>
- <dt>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is a cases-sensitive string match for
- <code>"SHA-256"</code>:
- </dt>
- <dd>
- Let <var>result</var> be the result of performing the SHA-256 hash function
- defined in Section 6.2 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
- <var>message</var> as the input message, <var>M</var>.
- </dd>
- <dt>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is a cases-sensitive string match for
- <code>"SHA-384"</code>:
- </dt>
- <dd>
- Let <var>result</var> be the result of performing the SHA-384 hash function
- defined in Section 6.5 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
- <var>message</var> as the input message, <var>M</var>.
- </dd>
- <dt>
- If the <a href="#dfn-Algorithm-name">name</a> member of
- <var>normalizedAlgorithm</var> is a cases-sensitive string match for
- <code>"SHA-512"</code>:
- </dt>
- <dd>
- Let <var>result</var> be the result of performing the SHA-1 hash function
- defined in Section 6.4 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
- <var>message</var> as the input message, <var>M</var>.
- </dd>
- </dl>
- </li>
- <li>
- <p>
- If performing the operation results in an error, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return a new ArrayBuffer containing <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
- <div id="concatkdf" class="section">
- <h3>34. Concat KDF</h3>
- <div id="concatkdf-description" class="section">
- <h4>34.1. Description</h4>
- <p>
- The <code>"CONCAT"</code> algorithm identifier is used to perform key derivation
- using the key derivation algorithm defined in Section 5.8.1 of NIST SP 800-56A
- [<a href="#SP800-56A">SP800-56A</a>] using the SHA hash functions defined
- in this specification.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with Concat KDF. Such specifications
- must define digest operations for the additional hash algorithms and
- <dfn id="dfn-concat-extended-import-steps">key import steps</dfn> for Concat KDF.
- </p>
- </div>
- <div id="concatkdf-registration" class="section">
- <h4>34.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"CONCAT"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>deriveBits</td>
- <td><a href="#dfn-ConcatParams">ConcatParams</a></td>
- <td><a href="#dfn-octet-string">Octet string</a></td>
- </tr>
- <tr>
- <td>Import key</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>Get key length</td>
- <td>None</td>
- <td>Integer or null</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="concat-params" class="section">
- <h4>34.3. ConcatParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-ConcatParams">ConcatParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The digest method to use to derive the keying material.</span>
-<a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-ConcatParams-hash">hash</dfn>;
-
-<span class="comment">// A bit string corresponding to the AlgorithmId field of the OtherInfo parameter.</span>
-<span class="comment">// The AlgorithmId indicates how the derived keying material will be parsed and for which</span>
-<span class="comment">// algorithm(s) the derived secret keying material will be used.</span>
-required BufferSource <dfn id="dfn-ConcatParams-algorithmId">algorithmId</dfn>;
-<span class="comment">// A bit string that corresponds to the PartyUInfo field of the OtherInfo parameter.</span>
-required BufferSource <dfn id="dfn-ConcatParams-partyUInfo">partyUInfo</dfn>;
-<span class="comment">// A bit string that corresponds to the PartyVInfo field of the OtherInfo parameter.</span>
-required BufferSource <dfn id="dfn-ConcatParams-partyVInfo">partyVInfo</dfn>;
-<span class="comment">// An optional bit string that corresponds to the SuppPubInfo field of the OtherInfo parameter.</span>
-BufferSource <dfn id="dfn-ConcatParams-publicInfo">publicInfo</dfn>;
-<span class="comment">// An optional bit string that corresponds to the SuppPrivInfo field of the OtherInfo parameter.</span>
-BufferSource <dfn id="dfn-ConcatParams-privateInfo">privateInfo</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="concat-operations" class="section">
- <h4>34.4. Operations</h4>
- <dl>
- <dt>Derive Bits</dt>
- <dd>
- <ol>
- <li>
- <p>
- Let <var>secret</var> be the result of performing the Concatenation Key
- Derivation Function defined in Section 5.8.1 of
- [<a href="#SP800-56A">SP800-56A</a>] with <var>length</var> as
- <var>keydatalen</var>, the hash function identified by the
- <a href="#dfn-ConcatParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var> as <var>H</var>, the
- <a href="#dfn-ConcatParams-algorithmId">algorithmId</a> member of
- <var>normalizedAlgorithm</var> as <var>AlgorithmID</var>, the
- <a href="#dfn-ConcatParams-partyUInfo">partyUInfo</a> member of
- <var>normalizedAlgorithm</var> as <var>PartyUInfo</var>, the
- <a href="#dfn-ConcatParams-partyVInfo">partyVInfo</a> member of
- <var>normalizedAlgorithm</var> as <var>PartyVInfo</var>, the
- <a href="#dfn-ConcatParams-publicInfo">publicInfo</a> member of
- <var>normalizedAlgorithm</var>, if present, as
- <var>SuppPubInfo</var> and the
- <a href="#dfn-ConcatParams-privateInfo">privateInfo</a> member of
- <var>normalizedAlgorithm</var>, if present, as
- <var>SuppPrivInfo</var>.
- </p>
- </li>
- <li>
- <p>
- If the operation fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return <var>secret</var>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <p>
- Perform any <a href="#dfn-concat-extended-import-steps">key import steps</a>
- defined by <a href="#dfn-applicable-specifications">other applicable
- specifications</a>, passing <var>keyData</var> and obtaining <var>result</var>.
- <dl class="switch">
- <dt>
- If <var>result</var> is a <a href="#dfn-CryptoKey">CryptoKey</a>
- object
- </dt>
- <dd>
- <p>
- Return <var>result</var>.
- </p>
- </dd>
- <dt>
- If <var>result</var> is an error with a name that is not
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
- </dt>
- <dd>
- <p>
- <a href="#concept-throw">throw</a> <var>result</var>.
- </p>
- </dd>
- </dl>
- </p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is <code>"raw"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value that is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>,
-
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the key data provided in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"secret"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"CONCAT"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Get length</dt>
- <dd>
- <ol>
- <li>
- <p>
- Return null.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
- <div id="hkdf-ctr" class="section">
- <h3>35. HKDF-CTR</h3>
- <div id="hkdf-ctr-description" class="section">
- <h4>35.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"HKDF-CTR"</code> algorithm identifier is used to
- perform key derivation using the extraction-then-expansion approach described in
- NIST SP 800-56C[<a href="#SP800-56C">SP800-56C</a>], using HMAC in counter mode, and
- using the SHA hash functions defined in this specification
- as described in Section 5.1 of NIST SP 800-108
- [<a href="#SP800-108">SP800-108</a>].
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with HKDF.
- Such specifications must define the digest operation for the additional hash algorithms.
- </p>
- </div>
- <div id="hkdf-ctr-registration" class="section">
- <h4>35.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a>
- for this algorithm is <code>"HKDF-CTR"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>deriveBits</td>
- <td><a href="#dfn-HkdfCtrParams">HkdfCtrParams</a></td>
- <td><a href="#dfn-ArrayBuffer">ArrayBuffer</a></td>
- </tr>
- <tr>
- <td>Import key</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>Get key length</td>
- <td>None</td>
- <td>Integer or null</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="hkdf-ctr-params" class="section">
- <h4>35.3. HkdfCtrParams dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-HkdfCtrParams">HkdfCtrParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-<span class="comment">// The algorithm to use with HMAC (e.g.: <a href="#sha-256">SHA-256</a>)</span>
-required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HkdfCtrParams-hash">hash</dfn>;
-<span class="comment">// A bit string that corresponds to the label that identifies the purpose for the derived keying material.</span>
-required BufferSource <dfn id="dfn-HkdfCtrParams-label">label</dfn>;
-<span class="comment">// A bit string that corresponds to the context of the key derivation, as described in Section 5 of NIST SP 800-108 [<a href="#SP800-108">SP800-108</a>]</span>
-required BufferSource <dfn id="dfn-HkdfCtrParams-context">context</dfn>;
-};
- </code></pre></div></div>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- The definition of HKDF allows the caller to supply an optional pseudorandom salt
- value, which is used as the key during the extract phase. If this value is not
- supplied, an all zero string is used instead. However, support for an explicit
- salt value is not widely implemented in existing APIs, nor is it required by
- existing usages of HKDF. Should this be an optional parameter, and if so, what
- should the behavior be of a user agent that does not support explicit salt
- values (is it conforming or non-conforming?)
- </p>
- </div>
- </div>
- <div id="hkdf2-ctr-operations" class="section">
- <h4>35.4. Operations</h4>
- <dl>
- <dt>Derive Bits</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>length</var> is null, then <a href="#concept-throw">throw</a> a <a href="#dfn-TypeError"><code>TypeError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var> does not describe a <a href="#algorithms">
- recognized algorithm</a> that supports the digest operation, then
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
- </p>
- </li>
- <li>
- <p>
- Let <var>extractKey</var> be a key equal to <var>n</var> zero bits where
- <var>n</var> is the size of the output of the hash function described by the
- <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>prf</var> be the MAC Generation function described in Section 4 of
- [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using the hash function
- described by the <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>keyDerivationKey</var> be the result of performing <var>prf</var>
- using <var>extractKey</var> as the key and the secret represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- as the message.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the KDF in counter
- mode operation described in Section 5.1 of NIST SP 800-108
- [<a href="#SP800-108">SP800-108</a>] using:
- </p>
- <ul>
- <li>
- <p>
- <var>prf</var> as the Pseudo-Random Function, <var>PRF</var>,
- </p>
- </li>
- <li>
- <p>
- <var>keyDerivationKey</var> as the Key derivation key,
- <var>K<sub>I</sub></var>,
- </p>
- </li>
- <li>
- <p>
- <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-HkdfCtrParams-label">label</a> member of
- <var>normalizedAlgorithm</var> as <var>Label</var>,
- </p>
- </li>
- <li>
- <p>
- <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-HkdfCtrParams-label">context</a> member of
- <var>normalizedAlgorithm</var> as <var>Context</var>,
- </p>
- </li>
- <li>
- <p>
- <var>length</var> as the value of <var>L</var>,
- </p>
- </li>
- <li>
- <p>
- 32 as the value of <var>r</var>, and
- </p>
- </li>
- <li>
- <p>
- the 32-bit little-endian binary encoding of <var>length</var>
- as the encoded length value [<var>L</var>]<sub>2</sub>.
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p>
- If the key derivation operation fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return <var>result</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import key</dt>
- <dd>
- <ol>
- <li>
- <p>Let <var>keyData</var> be the key data to be imported.</p>
- </li>
- <li>
- <dl class="switch">
- <dt>
- If <var>format</var> is <code>"raw"</code>:
- </dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value that is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>,
-
- then <a href="#concept-throw">throw</a> a
- <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the key data provided in <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"secret"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new
- <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"HKDF-CTR"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Otherwise:</dt>
- <dd>
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
- </dd>
- </dl>
- </li>
- </ol>
- </dd>
- <dt>Get length</dt>
- <dd>
- <ol>
- <li>
- <p>
- Return null.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
- <div id="pbkdf2" class="section">
- <h3>36. PBKDF2</h3>
- <div id="pbkdf2-description" class="section">
- <h4>36.1. Description</h4>
- <p class="norm">This section is non-normative.</p>
- <p>
- The <code>"PBKDF2"</code> algorithm identifier is used to
- perform key derivation using the PKCS#5 password-based key
- derivation function version 2.0, as defined in
- [<a href="#rfc2898">RFC2898</a>] using HMAC as the pseudo-random function,
- using the SHA hash functions defined
- in this specification.
- </p>
- <p>
- <a href="#dfn-applicable-specification">Other specifications</a>
- may specify the use of additional hash algorithms with PBKDF2. Such specifications
- must define the digest operation for the additional hash algorithms.
- </p>
- </div>
- <div id="pbkdf2-registration" class="section">
- <h4>36.2. Registration</h4>
- <p>
- The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
- this algorithm is <code>"PBKDF2"</code>.
- </p>
- <table>
- <thead>
- <tr>
- <th><a href="#supported-operations">Operation</a></th>
- <th><a href="#algorithm-specific-params">Parameters</a></th>
- <th><a href="#algorithm-result">Result</a></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>generateKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>deriveBits</td>
- <td><a href="#dfn-Pbkdf2Params">Pbkdf2Params</a></td>
- <td><a href="#dfn-ArrayBuffer">ArrayBuffer</a></td>
- </tr>
- <tr>
- <td>importKey</td>
- <td>None</td>
- <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
- </tr>
- <tr>
- <td>Get key length</td>
- <td>None</td>
- <td>Length or null</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="pbkdf2-params" class="section">
- <h4>36.3. Pbkdf2Params dictionary</h4>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
-dictionary <dfn id="dfn-Pbkdf2Params">Pbkdf2Params</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
-required BufferSource <dfn id="dfn-Pbkdf2Params-salt">salt</dfn>;
-[EnforceRange] required unsigned long <dfn id="dfn-Pbkdf2Params-iterations">iterations</dfn>;
-required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-Pbkdf2Params-hash">hash</dfn>;
-};
- </code></pre></div></div>
- </div>
- <div id="pbkdf2-operations" class="section">
- <h4>36.4. Operations</h4>
- <dl>
- <dt>Derive bits</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>length</var> is null or is not a multiple of 8, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If the <a href="#dfn-Pbkdf2Params-hash">hash</a> member of
- <var>normalizedAlgorithm</var> does not describe a <a href="#algorithms">
- recognized algorithm</a> that supports the digest operation, then
- <a href="#concept-throw">throw</a> a
- <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
- </p>
- </li>
- <li>
- <p>
- Let <var>prf</var> be the MAC Generation function described in Section 4 of
- [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using the hash function
- described by the <a href="#dfn-Pbkdf2Params-hash">hash</a> member of
- <var>normalizedAlgorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Let <var>result</var> be the result of performing the PBKDF2 operation defined
- in Section 5.2 of [<a href="#rfc2898">RFC2898</a>] using <var>prf</var> as the
- pseudo-random function, <var>PRF</var>, the password represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
- as the password, <var>P</var>, <a href="#concept-contents-of-arraybuffer">the
- contents of</a> the <a href="#dfn-Pbkdf2Params-salt">salt</a> attribute of
- <var>normalizedAlgorithm</var> as the salt, <var>S</var>, the value of the <a href="#dfn-Pbkdf2Params-iterations">iterations</a> attribute of
- <var>normalizedAlgorithm</var> as the iteration count, <var>c</var>, and
- <var>length</var> divided by 8 as the intended key length, <var>dkLen</var>.
- </p>
- </li>
- <li>
- <p>
- If the key derivation operation fails,
- then <a href="#concept-throw">throw</a> an
- <a href="#dfn-OperationError"><code>OperationError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Return <var>result</var>
- </p>
- </li>
- </ol>
- </dd>
- <dt>Generate key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>usages</var> contains a value that is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>, then
- <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- If <var>extractable</var> is true, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Generate a new password by prompting the user.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing the provided password as a series of bytes encoded using UTF-8.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"secret"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"PBKDF2"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
- slot of <var>key</var> to <var>extractable</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
- <var>key</var> to the <a href="#concept-normalized-usages">normalized
- value</a> of <var>usages</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Import key</dt>
- <dd>
- <ol>
- <li>
- <p>
- If <var>format</var> is not <code>"raw"</code>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
- </p>
- </li>
- <li>
- <p>
- If <var>usages</var> contains a value that is not
- <code>"deriveKey"</code> or <code>"deriveBits"</code>, then
- <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
- </p>
- </li>
- <li>
- <p>
- Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
- representing <var>keyData</var>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
- <var>key</var> to <code>"secret"</code>.
- </p>
- </li>
- <li>
- <p>
- Let <var>algorithm</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
- object.
- </p>
- </li>
- <li>
- <p>
- Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
- <var>algorithm</var> to <code>"PBKDF2"</code>.
- </p>
- </li>
- <li>
- <p>
- Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
- slot of <var>key</var> to <var>algorithm</var>.
- </p>
- </li>
- <li>
- <p>
- Return <var>key</var>.
- </p>
- </li>
- </ol>
- </dd>
- <dt>Get length</dt>
- <dd>
- <ol>
- <li>
- <p>
- Return null.
- </p>
- </li>
- </ol>
- </dd>
- </dl>
- </div>
- </div>
-
-
- <div id="examples-section" class="section">
- <h2>37. JavaScript Example Code</h2>
- <div id="examples-signing" class="section">
- <h3>37.1. Generate a signing key pair, sign some data</h3>
-
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-<span class="comment">// Algorithm Object</span>
-var algorithmKeyGen = {
- name: "RSASSA-PKCS1-v1_5",
- <span class="comment">// <a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></span>
- modulusLength: 2048,
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]), <span class="comment">// Equivalent to 65537</span>
- hash: {
- name: "SHA-256"
- }
-};
-
-var algorithmSign = {
- name: "RSASSA-PKCS1-v1_5"
-};
-
-window.crypto.subtle.generateKey(algorithmKeyGen, false, ["sign"]).then(
- function(key) {
- var dataPart1 = convertPlainTextToArrayBufferView("hello,");
- var dataPart2 = convertPlainTextToArrayBufferView(" world!");
- <span class="comment">// TODO: create example utility function that converts text -> ArrayBufferView</span>
-
- return window.crypto.subtle.sign(algorithmSign, key.privateKey, [dataPart1, dataPar2]);
- },
- console.error.bind(console, "Unable to generate a key")
-).then(
- console.log.bind(console, "The signature is: "),
- console.error.bind(console, "Unable to sign")
-);
- </code></pre></div></div>
- </div>
- <div id="examples-symmetric-encryption" class="section">
- <h3>37.2. Symmetric Encryption</h3>
- <div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-var clearDataArrayBufferView = convertPlainTextToArrayBufferView("Plain Text Data");
-<span class="comment">// TODO: create example utility function that converts text -> ArrayBufferView</span>
-
-var aesAlgorithmKeyGen = {
- name: "AES-CBC",
- <span class="comment">// <a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></span>
- length: 128
-};
-
-var aesAlgorithmEncrypt = {
- name: "AES-CBC",
- <span class="comment">// <a href="#dfn-AesCbcParams">AesCbcParams</a></span>
- iv: window.crypto.getRandomValues(new Uint8Array(16))
-};
-
-<span class="comment">// Create a key generator to produce a one-time-use AES key to encrypt some data</span>
-window.crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(
- function(aesKey) {
- return window.crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, [ clearDataArrayBufferView ]);
- }
-).then(console.log.bind(console, "The ciphertext is: "),
- console.error.bind(console, "Unable to encrypt"));
- </code></pre></div></div>
- </div>
- </div>
- <div id="iana-section" class="section">
- <h2>38. IANA Considerations</h2>
- <div id="iana-section-jws-jwa" class="section">
- <h3>38.1. JSON Web Signature and Encryption Algorithms Registration</h3>
- <p>
- This section registers the following algorithm identifiers in the IANA JSON Web
- Signature and Encryption Algorithms Registry for use with JSON Web Key. Note that the
- 'Implementation Requirements' field in the template refers to use with JSON Web
- Signature and JSON Web Encryption specifically, in which case use of unauthenticated
- encryption is prohibited.
- </p>
- <ul>
- <li>Algorithm Name: "RS1"</li>
- <li>Algorithm Description: RSASSA-PKCS1-v1_5 with SHA-1</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "RSA-OAEP-384"</li>
- <li>Algorithm Description: RSA-OAEP using SHA-384 and MGF1 with SHA-384</li>
- <li>Algorithm Usage Location(s): "alg"</li>
- <li>JOSE Implementation Requirements: Optional+</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "RSA-OAEP-512"</li>
- <li>Algorithm Description: RSA-OAEP using SHA-512 and MGF1 with SHA-512</li>
- <li>Algorithm Usage Location(s): "alg"</li>
- <li>JOSE Implementation Requirements: Optional+</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A128CBC"</li>
- <li>Algorithm Description: AES CBC using 128 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A192CBC"</li>
- <li>Algorithm Description: AES CBC using 192 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A256CBC"</li>
- <li>Algorithm Description: AES CBC using 256 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A128CTR"</li>
- <li>Algorithm Description: AES CTR using 128 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A192CTR"</li>
- <li>Algorithm Description: AES CTR using 192 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A256CTR"</li>
- <li>Algorithm Description: AES CTR using 256 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A128CMAC"</li>
- <li>Algorithm Description: AES CMAC using 128 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A192CMAC"</li>
- <li>Algorithm Description: AES CMAC using 192 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A256CMAC"</li>
- <li>Algorithm Description: AES CMAC using 256 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A128CFB8"</li>
- <li>Algorithm Description: AES CFB-8 using 128 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A192CFB8"</li>
- <li>Algorithm Description: AES CFB-8 using 192 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "A256CFB8"</li>
- <li>Algorithm Description: AES CFB-8 using 256 bit key</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- <ul>
- <li>Algorithm Name: "HS1"</li>
- <li>Algorithm Description: HMAC using SHA-1</li>
- <li>Algorithm Usage Location(s): "JWK"</li>
- <li>JOSE Implementation Requirements: Prohibited</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document ]]</li>
- </ul>
- </div>
- <div id="iana-section-jwk" class="section">
- <h3>38.2. JSON Web Key Parameters Registration</h3>
- <ul>
- <li>Parameter Name: "ext"</li>
- <li>Parameter Description: Extractable</li>
- <li>Used with "kty" Value(s): *</li>
- <li>Parameter Information Class: Public</li>
- <li>Change Controller: W3C Web Cryptography Working Group</li>
- <li>Specification Document(s): [[ This Document]]</li>
- </ul>
- </div>
- </div>
- <div id="acknowledgements-section" class="section">
- <h2>39. Acknowledgements</h2>
- <p>
- The editors would like to thank Adam Barth, Alex Russell, Ali Asad, Arun Ranganathan,
- Brian Smith, Brian Warner, Channy Yun, Eric Roman, Glenn Adams, Jim Schaad, Kai Engert,
- Mark Watson, Michael Hutchinson, Michael B. Jones, Nick Van den Bleeken, Richard Barnes,
- Vijay Bharadwaj, Virginie Galindo, and Wan-Teh Chang for their technical feedback and
- assistance.
- </p>
- <p>
- Thanks to the W3C Web Cryptography WG, and to participants on the public-webcrypto@w3.org
- mailing list.
- </p>
- <p>
- The W3C would like to thank the <a href="http://certdata.northropgrumman.com/cybersecurity/presskit_research_co.html">Northrop
- Grumman Cybersecurity Research Consortium</a> for supporting W3C/MIT.
- </p>
- <p>
- The <a href="#dfn-Crypto-method-getRandomValues"><code>getRandomValues</code></a>
- method in the <code>Crypto</code> interface was originally proposed by Adam Barth to the
- <a href="http://wiki.whatwg.org/wiki/Crypto">WHATWG</a>.
- </p>
- </div>
- <div id="references" class="section">
- <h2>40. References</h2>
- <div id="normative-references" class="section">
- <h3>40.1. Normative References</h3>
- <dl>
- <dt id="DOM4">DOM4</dt>
- <dd>
- <cite><a href="http://dom.spec.whatwg.org/">DOM (Living Standard)</a></cite>,
- A. Gregor, A. van Kesteren, Ms2ger. WHATWG.
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>This will be updated to W3C DOM4 once Promises are incorporated.</div>
- </dd>
- <dt id="ECMA-262">ECMA262</dt>
- <dd>
- <cite><a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
- ECMAScript 5th Edition</a></cite>, A. Wirfs-Brock, P. Lakshman et al.
- </dd>
- <dt id="FIPS180-4">FIPS 180-4</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf">
- FIPS PUB 180-4: Secure Hash Standard</a></cite>, NIST.
- </dd>
- <dt id="HTML">HTML</dt>
- <dd>
- <cite><a href="http://dev.w3.org/html5/spec/Overview.html">HTML5: A vocabulary and
- associated APIs for HTML and XHTML (work in progress)</a></cite>, I. Hickson. W3C.
- </dd>
- <dt id="PKCS3">PKCS3</dt>
- <dd>
- <cite><a href="http://www.rsa.com/rsalabs/node.asp?id=2126">PKCS #3: Diffie-Hellman
- Key-Agreement Standard</a></cite>, RSA Laboratories.
- </dd>
- <dt id="RFC2119">RFC2119</dt>
- <dd>
- <cite><a href="http://www.ietf.org/rfc/rfc2119">Key words for use in RFCs to
- Indicate Requirement Levels</a></cite>, S. Bradner. IETF.
- </dd>
- <dt id="RFC3447">RFC3447</dt>
- <dd>
- <cite><a href="http://www.ietf.org/rfc/rfc3447">Public-Key Cryptography Standards
- (PKCS) #1: RSA Cryptography Specifications Version 2.1</a></cite>, J. Jonsson,
- B. Kaliski. IETF.
- </dd>
- <dt id="RFC5208">RFC5208</dt>
- <dd>
- <cite><a href="http://www.ietf.org/rfc/rfc5208.txt">Public-Key Cryptography Standards
- (PKCS) #8: Private-Key Information Syntax Specification Version 1.2</a></cite>,
- B. Kaliski. IETF.
- </dd>
- <dt id="RFC5280">RFC5280</dt>
- <dd>
- <cite><a href="http://www.ietf.org/rfc/rfc5280.txt">Internet X.509 Public Key
- Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a></cite>,
- D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk. IETF.
- </dd>
- <dt id="WebIDL">Web IDL (Second Edition)</dt>
- <dd>
- <cite><a href="http://heycam.github.io/webidl/">Web IDL (Second Edition)</a></cite>,
- C. McCormack.
- </dd>
- <dt id="X9.62">X9.62</dt>
- <dd>
- <cite>ANS X9.62–2005: Public Key Cryptography for the Financial Services Industry,
- The Elliptic Curve Digital Signature Algorithm (ECDSA)</cite>, ANSI.
- </dd>
- <dt id="X9.63">X9.63</dt>
- <dd>
- <cite>ANS X9.63–2001: Public Key Cryptography for the Financial Services Industry,
- Key Agreement and Key Transport Using Elliptic Curve Cryptography</cite>, ANSI.
- </dd>
- <dt id="jwk">JSON Web Key</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-key">JSON Web Key
- (work in progress)</a></cite>, M. Jones, Microsoft.
- </dd>
- <dt id="jwa">JSON Web Algorithms</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms">JSON
- Web Algorithms (work in progress)</a></cite>, M. Jones, Microsoft.
- </dd>
- <dt id="rfc3394">RFC3394</dt>
- <dd>
- <cite><a href="http://www.ietf.org/rfc/rfc3394.txt">Advanced Encryption Standard
- (AES) Key Wrap Algorithm</a></cite>, J. Schaad, R. Housley, IETF.
- </dd>
- <dt id="fips-pub-198-1">FIPS PUB 198-1</dt>
- <dd>
- <cite>
- <a href="http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf">
- The Keyed-Hash Message Authentication Code (HMAC)
- </a>
- </cite>,
- July 2008, NIST.
- </dd>
- </dl>
- </div>
- <div id="informative-references" class="section">
- <h3>40.2. Informative References</h3>
- <dl>
- <dt id="CDSA">CDSA</dt>
- <dd>
- <cite><a href="http://www.opengroup.org/security/cdsa.htm">Common Security: CDSA and
- CSSM, Version 2 (with corrigenda)</a></cite>, the Open Group.
- </dd>
- <dt id="CNG">CNG</dt>
- <dd>
- <cite><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx">
- Cryptography API: Next Generation</a></cite>, Microsoft Corporation.
- </dd>
- <dt id="CryptoAPI">CryptoAPI</dt>
- <dd>
- <cite><a href="http://msdn.microsoft.com/en-us/library/aa380256.aspx">Cryptography
- Reference</a></cite>, Microsoft Corporation.
- </dd>
- <dt id="draft-TLS-OBC">DRAFT-TLS-OBC</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/draft-balfanz-tls-obc-01">TLS Origin-Bound
- Certificates</a></cite>, D. Balfanz, D. Smetters, M. Upadhyay, A. Barth. IETF.
- </dd>
- <dt id="FileAPI">FileAPI</dt>
- <dd>
- <cite><a href="http://www.w3.org/TR/FileAPI/">File API</a></cite>,
- A. Ranganathan, J. Sicking. W3C.
- </dd>
- <dt id="IndexedDB">Indexed Database API</dt>
- <dd>
- <cite><a href="http://www.w3.org/TR/IndexedDB/">Indexed Database API</a></cite>,
- N. Mehta, J. Sicking, E. Graff, A. Popescu, J. Orlow, J. Bell. W3C.
- </dd>
- <dt id="PKCS11">PKCS11</dt>
- <dd>
- <cite><a href="http://www.rsa.com/rsalabs/node.asp?id=2133">PKCS #11: Cryptographic
- Token Interface Standard</a></cite>, RSA Laboratories.
- </dd>
- <dt id="RFC2315">RFC 2315</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/rfc2315">PKCS #7: Cryptographic
- Message Syntax, Version 1.5</a></cite>, B. Kaliski. RSA Laboratories.
- </dd>
- <dt id="RFC2898">RFC 2898</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/rfc2898">PKCS #5: Password-Based
- Cryptography Specification, Version 2.0</a></cite>, B. Kaliski. RSA Laboratories
- </dd>
- <dt id="RFC5705">RFC 5705</dt>
- <dd>
- <cite><a href="http://tools.ietf.org/html/rfc5705">Keying Material Exporters for
- Transport Layer Security (TLS)</a></cite>, E. Rescorla. IETF.
- </dd>
- <dt id="RFC5869">RFC 5869</dt>
- <dd>
- <cite><a href="https://tools.ietf.org/html/rfc5869">HMAC-based Extract-and-Expand
- Key Derivation Function (HKDF)</a></cite>, H. Krawczyk, P. Eronen. IETF.
- </dd>
- <dt id="RFC4055">RFC 4055</dt>
- <dd>
- <cite><a href="https://tools.ietf.org/html/rfc4055">Additional Algorithms and
- Identifiers for RSA Cryptography for use in the Internet X.509 Public Key
- Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a></cite>,
- J. Schaad, B. Kaliski, R. Housley. IETF.
- </dd>
- <dt id="SP800-38A">NIST SP 800-38A</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf">
- NIST Special Publication 800-38A: Recommendation for Block Cipher
- Modes of Operation, Methods and Techniques</a></cite>, December 2001, NIST.
- </dd>
- <dt id="SP800-38B">NIST SP 800-38B</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf">
- NIST Special Publication 800-38B: Recommendation for Block Cipher Modes of Operation:
- The CMAC Mode for Authentication</a></cite>, May 2005, NIST.
- </dd>
- <dt id="SP800-38D">NIST SP 800-38D</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf">
- NIST Special Publication 800-38D: Recommendation for Block Cipher Modes of Operation:
- Galois/Counter Mode (GCM) and GMAC</a></cite>, November 2007, NIST.
- </dd>
- <dt id="SP800-56A">NIST SP 800-56A</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">
- NIST Special Publication 800-56A: Recommendation for Pair-Wise Key Establishment
- Schemes Using Discrete Logarithm Cryptography (Revised)</a></cite>, March 2007, NIST.
- </dd>
- <dt id="SP800-56C">NIST SP 800-56C</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf">
- NIST Special Publication 800-56C: Recommendation for Key Derivation through
- Extraction-then-Expansion</a></cite>, November 2011, NIST.
- </dd>
- <dt id="SP800-108">NIST SP 800-108</dt>
- <dd>
- <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-108/sp800-108.pdf">
- NIST Special Publication 800-108: Recommendation for Key Derivation Using
- Pseudorandom Functions (Revised)</a></cite>, October 2009, NIST.
- </dd>
- <dt id="StreamsAPI">StreamsAPI</dt>
- <dd>
- <cite><a href="http://dvcs.w3.org/hg/streams-api/raw-file/tip/Overview.htm">Streams
- API</a> </cite>, F. Moussa. W3C.
- </dd>
- </dl>
- </div>
- </div>
- </div>
-
- <div id="appendices">
- <div id="jwk-mapping" class="section">
- <h2>A. Mapping between JSON Web Key / JSON Web Algorithm</h2>
- <p class="norm">
- The following section is non-normative. Refer to algorithm-specific sections for the
- normative requirements of importing and exporting JWK.
- </p>
- <div id="jwk-mapping-alg" class="section">
- <h3>A.1. Algorithm mappings</h3>
- <table>
- <thead>
- <tr>
- <th scope="col">JSON Web Key</th>
- <th scope="col">AlgorithmIdentifier</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RS1" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSASSA-PKCS1-v1_5",
- hash: { name: "SHA-1" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RS256" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSASSA-PKCS1-v1_5",
- hash: { name: "SHA-256" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RS384" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSASSA-PKCS1-v1_5",
- hash: { name: "SHA-384" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RS512" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSASSA-PKCS1-v1_5",
- hash: { name: "SHA-512" }
-}
-</code></pre></div></div>
- </td>
- </tr>
-
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "PS256" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-PSS",
- hash: { name: "SHA-256" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "PS384" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-PSS",
- hash: { name: "SHA-384" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "PS512" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-PSS",
- hash: { name: "SHA-512" }
-}
-</code></pre></div></div>
- </td>
- </tr>
-
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RSA-OAEP" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-OAEP",
- hash: { name: "SHA-1" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RSA-OAEP-256" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-OAEP",
- hash: { name: "SHA-256" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RSA-OAEP-384" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-OAEP",
- hash: { name: "SHA-384" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "RSA",
- alg: "RSA-OAEP-512" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "RSA-OAEP",
- hash: { name: "SHA-512" }
-}
-</code></pre></div></div>
- </td>
- </tr>
-
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "EC",
- alg: "ES256" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "ECDSA",
- namedCurve: "P-256"
- hash: { name: "SHA-256" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "EC",
- alg: "ES384" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "ECDSA",
- namedCurve: "P-384"
- hash: { name: "SHA-384" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "EC",
- alg: "ES512" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "ECDSA",
- namedCurve: "P-521"
- hash: { name: "SHA-512" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128CTR" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CTR",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192CTR" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CTR",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256CTR" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CTR",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128CBC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CBC",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192CBC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CBC",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256CBC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CBC",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128KW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-KW",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192KW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-KW",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256KW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-KW",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128GCM" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192GCM" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256GCM" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128GCMKW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192GCMKW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256GCMKW" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-GCM",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128CMAC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CMAC",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192CMAC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CMAC",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256CMAC" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CMAC",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A128CFB8" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CFB-8",
- length: 128 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A192CFB8" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CFB-8",
- length: 192 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "A256CFB8" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "AES-CFB-8",
- length: 256 }
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "HS1" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "HMAC",
- hash: { name: "SHA-1" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "HS256" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "HMAC",
- hash: { name: "SHA-256" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "HS384" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "HMAC",
- hash: { name: "SHA-384" }
-}
-</code></pre></div></div>
- </td>
- </tr>
- <tr>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ kty: "oct",
- alg: "HS512" }
-</code></pre></div></div>
- </td>
- <td>
-<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
-{ name: "HMAC",
- hash: "SHA-512" }
-</code></pre></div></div>
- </td>
- </tr>
- </tbody>
- </table>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>Should the following be specified.</p>
- <ul>
- <li><p>RSASSA-PKCS1-v1_5 with SHA-1</p></li>
- <li><p>RSA-PSS with SHA-1</p></li>
- <li><p>ECDSA with SHA-1</p></li>
- <li>
- <p>
- ECDSA where the curve (P-256, P-384, P-521) is not aligned with the hash (SHA-256,
- SHA-384, SHA-512)
- </p>
- </li>
- </ul>
- </div>
- </div>
- <div id="jwk-mapping-usage" class="section">
- <h3>A.2. Usage mapping</h3>
- <table>
- <thead>
- <tr>
- <th scope="col">JWK <code>use</code> value</th>
- <th scope="col"><a href="#dfn-KeyUsage">KeyUsage</a>s</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>enc</code></td>
- <td><code>["encrypt", "decrypt", "wrapKey", "unwrapKey"]</code></td>
- </tr>
- <tr>
- <td><code>sig</code></td>
- <td><code>["sign","verify"]</code></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div id="spki-mapping" class="section">
- <h2>B. Mapping between Algorithm and SubjectPublicKeyInfo</h2>
- <p class="norm">
- The following section is non-normative. Refer to algorithm-specific sections for the
- normative requirements of importing and exporting SPKI.
- </p>
- <table>
- <thead>
- <tr>
- <th scope="col">Algorithm OID</th>
- <th scope="col">subjectPublicKey ASN.1 structure</th>
- <th scope="col">AlgorithmIdentifier</th>
- <th scope="col">Reference</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>rsaEncryption (1.2.840.113549.1.1.1)</td>
- <td>RSAPublicKey</td>
- <td>
- <code>"RSASSA-PKCS1-v1_5"</code>,
- <code>"RSA-PSS"</code>, or
- <code>"RSA-OAEP"</code>
- </td>
- <td>
- <a href="#RFC3279">RFC 3279</a>,
- <a href="#RFC4055">RFC 4055</a>,
- <a href="#RFC5756">RFC 5756</a>
- </td>
- </tr>
- <tr>
- <td>id-RSASSA-PSS (1.2.840.113549.1.1.10)</td>
- <td>RSAPublicKey</td>
- <td><code>"RSA-PSS"</code></td>
- <td>
- <a href="#RFC4055">RFC 4055</a>,
- <a href="#RFC5756">RFC 5756</a>
- </td>
- </tr>
- <tr>
- <td>id-RSAES-OAEP (1.2.840.113549.1.1.7)</td>
- <td>RSAPublicKey</td>
- <td><code>"RSA-OAEP"</code></td>
- <td>
- <a href="#RFC4055">RFC 4055</a>,
- <a href="#RFC5756">RFC 5756</a>
- </td>
- </tr>
- <tr>
- <td>id-ecPublicKey (1.2.840.10045.2.1)</td>
- <td>ECPoint</td>
- <td><code>"ECDH"</code> or <code>"ECDSA"</code></td>
- <td><a href="#RFC5480">RFC 5480</a></td>
- </tr>
- <tr>
- <td>id-ecDH (1.3.132.112)</td>
- <td>ECPoint</td>
- <td><code>"ECDH"</code></td>
- <td><a href="#RFC5480">RFC 5480</a></td>
- </tr>
- <tr>
- <td>id-dsa (1.2.840.10040.4.1)</td>
- <td>DSAPublicKey</td>
- <td><code>"DSA"</code></td>
- <td><a href="#RFC3279">RFC 3279</a></td>
- </tr>
- <tr>
- <td>dhKeyAgreement (1.2.840.113549.1.3.1)</td>
- <td>INTEGER</td>
- <td><code>"DH"</code></td>
- <td><a href="#PKCS3">PKCS #3</a></td>
- </tr>
- </tbody>
- </table>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- The handling of "id-RSASSA-PSS" and "id-RSAES-OAEP" are tricky.
- <a href="#RFC5756">RFC 5756</a> recommends implementations should not include parameters
- when PSS is used with a subjectPublicKeyInfo, and MUST NOT include parameters when OAEP
- is used. However, when OAEP is used as part of a key transport (as an AlgorithmIdentifier),
- implementations MUST include the parameters.
- </p>
- <p>
- The natural conflict is in deciding when a key is being exported as part of a
- subjectPublicKeyInfo (which is what "spki" implies) and when it's being used as an
- algorithmIdentifier for transport.
- </p>
- </div>
- </div>
- <div id="pkcs8-mapping" class="section">
- <h2>C. Mapping between Algorithm and PKCS#8 PrivateKeyInfo</h2>
- <p class="norm">
- The following section is non-normative. Refer to algorithm-specific sections for the
- normative requirements of importing and exporting PKCS#8 PrivateKeyInfo.
- </p>
- <table>
- <thead>
- <tr>
- <th scope="col">privateKeyAlgorithm</th>
- <th scope="col">privateKey format</th>
- <th scope="col">AlgorithmIdentifier</th>
- <th scope="col">Reference</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>rsaEncryption (1.2.840.113549.1.1.1)</td>
- <td>RSAPrivateKey</td>
- <td>
- <code>"RSASSA-PKCS1-v1_5"</code>,
- <code>"RSA-PSS"</code>, or
- <code>"RSA-OAEP"</code>
- </td>
- <td>
- <a href="#RFC3447">RFC 3447</a>,
- <a href="#RFC5958">RFC 5958</a>
- </td>
- </tr>
- <tr>
- <td>id-RSASSA-PSS (1.2.840.113549.1.1.10)</td>
- <td>RSAPrivateKey</td>
- <td><code>"RSA-PSS"</code></td>
- <td>
- <a href="#RFC3447">RFC 3447</a>,
- <a href="#RFC4055">RFC 4055</a>,
- <a href="#RFC5958">RFC 5958</a>
- </td>
- </tr>
- <tr>
- <td>id-RSAES-OAEP (1.2.840.113549.1.1.7)</td>
- <td>RSAPrivateKey</td>
- <td><code>"RSA-OAEP"</code></td>
- <td>
- <a href="#RFC3447">RFC 3447</a>,
- <a href="#RFC4055">RFC 4055</a>,
- <a href="#RFC5958">RFC 5958</a>
- </td>
- </tr>
- <tr>
- <td>id-ecPublicKey (1.2.840.10045.2.1)</td>
- <td>ECPrivateKey</td>
- <td><code>"ECDH"</code> or <code>"ECDSA"</code></td>
- <td>
- <a href="#RFC5480">RFC 5480</a>,
- <a href="#RFC5915">RFC 5915</a>,
- <a href="#RFC5958">RFC 5958</a>
- </td>
- </tr>
- <tr>
- <td>id-ecDH (1.3.132.112)</td>
- <td>ECPrivateKey</td>
- <td><code>"ECDH"</code></td>
- <td>
- <a href="#RFC5480">RFC 5480</a>,
- <a href="#RFC5915">RFC 5915</a>,
- <a href="#RFC5958">RFC 5958</a>
- </td>
- </tr>
- <tr>
- <td>id-dsa (1.2.840.10040.4.1)</td>
- <td>INTEGER</td>
- <td><code>"DSA"</code></td>
- <td><a href="#RFC5958">RFC 5958</a></td>
- </tr>
- <tr>
- <td>dhKeyAgreement (1.2.840.113549.1.3.1)</td>
- <td>INTEGER</td>
- <td><code>"DH"</code></td>
- <td><a href="#PKCS3">PKCS #3</a></td>
- </tr>
- </tbody>
- </table>
- <div class="ednote"><div class="ednoteHeader">Editorial note</div>
- <p>
- There does not appear to be a normative reference for a DH key being encoded as an
- INTEGER. Only RFC 5958 seems to mention this.
- </p>
- </div>
- </div>
- </div>
- </body>
-</html>