- From: Matt Miller <mamille2@cisco.com>
- Date: Thu, 24 Apr 2014 14:38:22 -0600
- To: <public-webcrypto-comments@w3.org>
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Hello all, Below are my comments after reading the current draft of WebCryptoAPI. I apologize if I've repeated anything stated before; I've not really followed the discussion leading up to this document's current state. Potential Defects: ============================================== The definition for "PBKDF2" includes an editor note that does not appear to be relevant. It discusses a "password" field that is not present in any of the immediately surrounding content. Comments: ============================================== Key Storage/Retrieval - ---------------------------------------------- The draft discusses "retrieving keys" -- distinct from import/unwrap - -- but does not in any other way indicate how this is dealt with. It would help to explicitly mention that key storage/retrieval can be done with mechanisms that support structured cloning, such as IndexedDB. KeyPairs and Extractability - ---------------------------------------------- Assuming that when generateKey returns a KeyPair that the public key is always extractable, this should be explicitly stated somewhere separate from the individually registered algorithms. At a minimum, this ought to be stated in § 18.3. "Defining an Algorithm", but it could also be helpful for have it stated at or around § 14.3.6. "The generateKey method" from the perspective of an API user. "Defining an algorithm" Guidelines - ---------------------------------------------- If the to-be-defined algorithm supports the "importKey" operation, the definition ought to clearly specify how [extractable] applies. Examples - ---------------------------------------------- It would be nice to a somewhat non-trivial deriveKey example. For my own edification, I put together a mythical example (included below) to see if I'm understanding the API interactions correctly. And, please, correct my misconceptions of how the API works if my example has egregious errors. Key Lifetimes - ---------------------------------------------- I suspect this is controversial. It would be nice if a generated Key could have some sort of lifetime that the user agent enforces. At a minimum, I would highly desire the ability to specify that a Key should not be used for more than a browser session (similar to sessionStorage), but would value having a fixed expiration date/time or a certain amount of time after generateKey's promise is fulfilled. I realize that this can complicate things (e.g., how does this interact with importKey?), and can live with some restrictions (e.g., limited-life Keys are never extractable). I think it's also acceptable for the lifetime to be tied to just the private Key of a KeyPair, if it helps simplify things at all. Thank you, - - m&m Matt Miller < mamille2@cisco.com > Cisco Systems, Inc. - -----BEGIN EXAMPLE----- // Agree to a session key with another user var promise, us = {}, them = {}, sessionKey = null; // helper for prefixing data with a length encoding function __UINT32(value) { var output = new Uint8Array([ (value >>> 24) & 0xff, (value >>> 16) & 0xff, (value >>> 8) & 0xff, value & 0xff ]); } // Generate an EC Key for ECDH var params = { name: "ECDH", namedCurve: "P-256" }; promise = window.crypto.subtle.generateKey(params, false, [ "deriveKey" ]); promise = promise.then(function (keypair) { // remember the generated key for right now us.pivateKey = keypair.privateKey; us.publicKey = keypair.publicKey; // set our identifier var ident = new TextEncoding("utf-8").encode("me@example.com"); us.info = new Uint8Array(4 + ident.byteLength); us.info.set(__UINT32(ident.byteLength)); us.info.set(ident, 4); // export public key as JWK return window.crypto.subtle.exportKey("jwk", us.publicKey); }); promise = promise.then(function(jwk) { // exchange public keys with 'them'; // returns a promise with the other user's public key, // it could use XMLHttpRequest or WebSocket for the actual exchnage return exchangePeerInfo({ publicKey: jwk, info: us.info }); }); promise = promise.then(function (other) { them = other; // import the key return window.crypto.subtle.importKey("jwk", them.key, { name: "ECDH" }, true, [ "deriveBits" ]); }); promise = promise.then(function (theirKey) { // remember their Key object them.publicKey = theirKey; // generate the shared secret "Key" var params = { name: "ECDH", public: their.publicKey }; return window.crypto.subtle.deriveKey(params, us.privateKey, { name: "CONCAT" }, false, [ "deriveKey" ]); }); promise = promise.then(function (secret) { // construct the algorithmId UINT32(algorithm.length) || algorithm var algName = new TextEncoder("utf-8").encode("A128GCM"); var algId = new Uint8Array(4 + algName.byteLength); algId.set(__UINT32(algName.byteLength)); algId.set(algName, 4); var params = { name: "CONCAT", hash: "SHA-256", algorithmsId: algId, partyUInfo: us.info, partyVInfo: them.info }; var derived = { name: "AES-GCM", length: 128 }; return window.crypto.subtle.deriveKey(params, secret, derived, false, [ "encrypt", "decrypt" ]); }); promise.then(console.log.bind(console, "the session key is: "), console.error.bind(console, "generating session key failed"); - -----END EXAMPLE----- -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.22 (Darwin) Comment: GPGTools - https://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCgAGBQJTWXY9AAoJEDWi+S0W7cO1RDAH/1kHELdgg9DDWTg9yalaL8NQ yo7Sn/HqyYH5UTFurlVahHuuZlcdeCtsH2cL5PnMQfqmKjCTCJ/iDzmaGpSX4Pt3 mAZIlQY15ze+WhA9b3noZkXoEGZJPwWN4nY7Xy07cBag0sEoWAJXKmgc2UMKNGbU aOMmxQzsp3gxLW7LXEEWFsD/iC1fzNLiyXSKZVUtBTI3Kkk3ic9FAP5tYXLggyEu Xk6jpPgLAxHF73M/E+xAxtPBpfDNbQUluAv9V6nTQwr1+ciaIYXeOoGClCgjwFkn AxpiPAdujre9e3VeVBgkJR+5tNVLFysxCqOBqIgxo2p1ODeFsYOXpHn27PfSrJY= =jl7W -----END PGP SIGNATURE-----
Received on Friday, 25 April 2014 13:28:06 UTC