Skip to content

Commit

Permalink
Rename Crypto -> SubtleCrypto, placing it in window.crypto.subtle
Browse files Browse the repository at this point in the history
One of the ongoing points of feedback/confusion is regarding the exposure of
low-level algorithms to web developers. Some view this as an inherently
dangerous proposition, because web developers can't or don't understand
cryptographic tradeoffs. However, such a low-level interface is necessary to
support a variety of web applications, including applications or libraries that
provide secure high-level compositions.

Because protocols vary in requirements, and because these compositions vary in
implementation, a low-level API is necessary to support them. However, to make
it clearer to developers that this is subtle and easy to get wrong (just like
any other aspect of development, if not more so), move the existing Crypto
interface into SubtleCrypto.
  • Loading branch information
Ryan Sleevi committed Jan 28, 2013
1 parent 7e0d591 commit 6adc231
Show file tree
Hide file tree
Showing 2 changed files with 285 additions and 183 deletions.
131 changes: 91 additions & 40 deletions spec/Overview-WebCryptoAPI.xml
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ interface <dfn id="dfn-RandomSource">RandomSource</dfn> {
<div class="note">
<p>
Do not generate keys using the <code>getRandomValues</code> method. Use the
<a href="#dfn-Crypto-method-generateKey"><code>generateKey</code></a> method instead.
<a href="#dfn-SubtleSubtleCrypto-method-generateKey"><code>generateKey</code></a> method instead.
</p>
</div>
</div>
Expand Down Expand Up @@ -1315,6 +1315,21 @@ interface <dfn id="dfn-KeyOperation">KeyOperation</dfn> : EventTarget {
<div id="crypto-interface" class="section">
<h2>Crypto interface</h2>
<x:codeblock language="idl">
interface <dfn id="dfn-Crypto">Crypto</dfn> {
readonly attribute <a href="#dfn-SubtleCrypto">SubtleCrypto</a> subtle;
};

<a href="#dfn-Crypto">Crypto</a> implements <a href="#dfn-RandomSource">RandomSource</a>;

partial interface Window {
readonly attribute <a href="#dfn-Crypto">Crypto</a> crypto;
};
</x:codeblock>
</div>

<div id="subtlecrypto-interface" class="section">
<h2>SubtleCrypto interface</h2>
<x:codeblock language="idl">
enum <dfn id="dfn-KeyFormat">KeyFormat</dfn> {
<span class="comment">// An unformatted sequence of bytes. Intended for secret keys.</span>
"raw",
Expand All @@ -1326,46 +1341,40 @@ enum <dfn id="dfn-KeyFormat">KeyFormat</dfn> {
"jwk",
};

interface <dfn id="dfn-Crypto">Crypto</dfn> {
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-Crypto-method-encrypt">encrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
interface <dfn id="dfn-SubtleCrypto">SubtleCrypto</dfn> {
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-encrypt">encrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-Key">Key</a> key,
optional ArrayBufferView? buffer = null);
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-Crypto-method-decrypt">decrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-decrypt">decrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-Key">Key</a> key,
optional ArrayBufferView? buffer = null);
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-Crypto-method-sign">sign</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-sign">sign</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-Key">Key</a> key,
optional ArrayBufferView? buffer = null);
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-Crypto-method-verify">verify</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-verify">verify</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-Key">Key</a> key,
ArrayBufferView signature,
optional ArrayBufferView? buffer = null);
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-Crypto-method-digest">digest</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-CryptoOperation">CryptoOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-digest">digest</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
optional ArrayBufferView? buffer = null);

<span class="comment">// TBD: <a href="https://www.w3.org/2012/webcrypto/track/issues/36">ISSUE-36</a></span>
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-Crypto-method-generateKey">generateKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-generateKey">generateKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
bool extractable = false,
<a href="#dfn-KeyUsage">KeyUsage</a>[] keyUsages = []);
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-Crypto-method-deriveKey">deriveKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-deriveKey">deriveKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
<a href="#dfn-Key">Key</a> baseKey,
<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a>? derivedKeyType,
bool extractable = false,
<a href="#dfn-KeyUsage">KeyUsage</a>[] keyUsages = []);

<span class="comment">// TBD: <a href="https://www.w3.org/2012/webcrypto/track/issues/35">ISSUE-35</a></span>
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-Crypto-method-importKey">importKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-importKey">importKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
ArrayBufferView keyData,
<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a>? algorithm,
bool extractable = false,
<a href="#dfn-KeyUsage">KeyUsage</a>[] keyUsages = []);
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-Crypto-method-exportKey">exportKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format, <a href="#dfn-Key">Key</a> key);
};

<a href="#dfn-Crypto">Crypto</a> implements <a href="#dfn-RandomSource">RandomSource</a>;

partial interface Window {
readonly attribute <a href="#dfn-Crypto">Crypto</a> crypto;
<a href="#dfn-KeyOperation">KeyOperation</a> <a href="#dfn-SubtleSubtleCrypto-method-exportKey">exportKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format, <a href="#dfn-Key">Key</a> key);
};
</x:codeblock>
<div class="ednote">
Expand All @@ -1386,12 +1395,54 @@ partial interface Window {
</li>
</ul>
</div>
<div id="crypto-interface-methods" class="section">
<div id="subtlecrypto-interface-description" class="section">
<h3>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 class="ednote">
<p>
Because of the subtleties associated with this API, the Web Cryptography Working
Group is also investigating providing a high-level API which provides a
comprehensive secure construction and messaging format, to allow new web
applications to exchange information without having to be aware of the cryptographic
subtleties associated with these individual algorithms.
</p>
<p>
It is likely that such a high-level API will produce messages using algorithms and
formats defined in the IETF JOSE Working Group, although this is still a topic of
discussion.
</p>
</div>
</div>
<div id="subtlecrypto-interface-methods" class="section">
<h3>Methods and Parameters</h3>
<div id="Crypto-method-encrypt" class="section">
<div id="SubtleCrypto-method-encrypt" class="section">
<h4>The encrypt method</h4>
<p>
The <dfn id="dfn-Crypto-method-encrypt"><code>encrypt</code></dfn>
The <dfn id="dfn-SubtleSubtleCrypto-method-encrypt"><code>encrypt</code></dfn>
method returns a new <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>
object that will encrypt data using the specified
<a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
Expand Down Expand Up @@ -1490,10 +1541,10 @@ partial interface Window {
</ol>
</div>

<div id="Crypto-method-decrypt" class="section">
<div id="SubtleCrypto-method-decrypt" class="section">
<h4>The decrypt method</h4>
<p>
The <dfn id="dfn-Crypto-method-decrypt"><code>decrypt</code></dfn>
The <dfn id="dfn-SubtleSubtleCrypto-method-decrypt"><code>decrypt</code></dfn>
method returns a new <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>
object that will decrypt data using the specified
<a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
Expand Down Expand Up @@ -1592,10 +1643,10 @@ partial interface Window {
</ol>
</div>

<div id="Crypto-method-sign" class="section">
<div id="SubtleCrypto-method-sign" class="section">
<h4>The sign method</h4>
<p>
The <dfn id="dfn-Crypto-method-sign"><code>sign</code></dfn> method
The <dfn id="dfn-SubtleSubtleCrypto-method-sign"><code>sign</code></dfn> method
returns a new <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>
object that will sign data using the specified
<a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
Expand Down Expand Up @@ -1693,10 +1744,10 @@ partial interface Window {
</ol>
</div>

<div id="Crypto-method-verify" class="section">
<div id="SubtleCrypto-method-verify" class="section">
<h4>The verify method</h4>
<p>
The <dfn id="dfn-Crypto-method-verify"><code>verify</code></dfn> method
The <dfn id="dfn-SubtleSubtleCrypto-method-verify"><code>verify</code></dfn> method
returns a new <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>
object that will verify data using the specified
<a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
Expand Down Expand Up @@ -1794,10 +1845,10 @@ partial interface Window {
</ol>
</div>

<div id="Crypto-method-digest" class="section">
<div id="SubtleCrypto-method-digest" class="section">
<h4>The digest method</h4>
<p>
The <dfn id="dfn-Crypto-method-digest"><code>digest</code></dfn> method returns
The <dfn id="dfn-SubtleSubtleCrypto-method-digest"><code>digest</code></dfn> method returns
a new <a href="#dfn-CryptoOperation"><code>CryptoOperation</code></a>
object that will digest data using the specified
<a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a>.
Expand Down Expand Up @@ -1895,10 +1946,10 @@ partial interface Window {
</ol>
</div>

<div id="Crypto-method-generateKey" class="section">
<div id="SubtleCrypto-method-generateKey" class="section">
<h4>The generateKey method</h4>
<p>
When invoked, <dfn id="dfn-Crypto-method-generateKey"><code>generateKey</code></dfn> <span class="RFC2119">MUST</span> perform the following steps:
When invoked, <dfn id="dfn-SubtleSubtleCrypto-method-generateKey"><code>generateKey</code></dfn> <span class="RFC2119">MUST</span> perform the following steps:
</p>
<ol>
<li>
Expand Down Expand Up @@ -1995,10 +2046,10 @@ partial interface Window {
</div>
</div>

<div id="Crypto-method-deriveKey" class="section">
<div id="SubtleCrypto-method-deriveKey" class="section">
<h4>The deriveKey method</h4>
<p>
When invoked, <dfn id="dfn-Crypto-method-deriveKey"><code>deriveKey</code></dfn> <span class="RFC2119">MUST</span> perform the following steps:
When invoked, <dfn id="dfn-SubtleSubtleCrypto-method-deriveKey"><code>deriveKey</code></dfn> <span class="RFC2119">MUST</span> perform the following steps:
</p>
<ol>
<li>
Expand Down Expand Up @@ -2104,12 +2155,12 @@ partial interface Window {
</div>
</div>

<div id="Crypto-method-importKey" class="section">
<h4>The <dfn id="dfn-Crypto-method-importKey">importKey</dfn> method</h4>
<div id="SubtleCrypto-method-importKey" class="section">
<h4>The <dfn id="dfn-SubtleSubtleCrypto-method-importKey">importKey</dfn> method</h4>
<p></p>
</div>
<div id="Crypto-method-exportKey" class="section">
<h4>The <dfn id="dfn-Crypto-method-exportKey">exportKey</dfn> method</h4>
<div id="SubtleCrypto-method-exportKey" class="section">
<h4>The <dfn id="dfn-SubtleSubtleCrypto-method-exportKey">exportKey</dfn> method</h4>
<p></p>
</div>

Expand Down Expand Up @@ -2182,7 +2233,7 @@ interface <dfn id="dfn-KeyPair">KeyPair</dfn> {
<p>
The Working Group is actively discussing means of discovering <code><a href="#dfn-Key">Key</a></code>
objects that are not not directly created by the application via
<code><a href="#Crypto-method-generateKey">generateKey</a></code>, or allowing
<code><a href="#SubtleCrypto-method-generateKey">generateKey</a></code>, or allowing
web applications to indicate how and where the cryptographic keying material associated with
<code>Key</code> objects is stored. Examples of such <code>Key</code> objects or interfaces that
may be exposed include:
Expand Down Expand Up @@ -3575,7 +3626,7 @@ var algorithmSign = {
}
};

var keyGen = window.crypto.generateKey(algorithmKeyGen,
var keyGen = window.crypto.subtle.generateKey(algorithmKeyGen,
false, <span class="comment">// extractable</span>
["sign"]);

Expand Down Expand Up @@ -3628,7 +3679,7 @@ var aesAlgorithmEncrypt = {
};

<span class="comment">// Create a keygenerator to produce a one-time-use AES key to encrypt some data</span>
var cryptoKeyGen = window.crypto.generateKey(aesAlgorithmKeyGen,
var cryptoKeyGen = window.crypto.subtle.generateKey(aesAlgorithmKeyGen,
false, <span class="comment">// extractable</span>
["encrypt"]);

Expand All @@ -3638,7 +3689,7 @@ cryptoKeyGen.oncomplete = function(event) {

<span class="comment">// Unlike the signing example, which showed multi-part encryption, here we
// will perform the entire AES operation in a single call.</span>
var aesOp = window.crypto.encrypt(aesAlgorithmEncrypt, aesKey, clearDataArrayBufferView);
var aesOp = window.crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, clearDataArrayBufferView);
aesOp.oncomplete = function(event) {
<span class="comment">// The clearData has been encrypted.</span>
var ciphertext = event.target.result; <span class="comment">// ArrayBufferView</span>
Expand Down

0 comments on commit 6adc231

Please sign in to comment.