Deliverable high level API

From W3C Web Cryptography Wiki
Jump to: navigation, search

The WG expects to progress on this high level API, following different opinion expressed by the web developer community and some security experts. This work will start first with a definition of features of what could be expected from a high level API. Nevertheless some example of implementations can be found under the following links :

- Mozilla [1] and David Dahl post [2]

- Stanford Javascript Crypto Library [3]

- KeycZar [4]

- NaCl ("salt") [5]


Some of the criticism the WG received about the complexity of the high level API were also discussed. Some participants of the Web Crypto WG (BBN, Microsoft, Inventive Designers, Mozilla) have decided to work on a set of pre-defined packaged operations, similar to the ones defined in IETF JOSE WG. First thoughts about it can be found below.

On Crypto API Safety in the Hands of Unskilled Developers ( By Richard Barnes, BBN)

1. What is the problem?

Conceptually, there are two classes of CryptoOperation: "Plain to ciphertext" operations that convert plaintext to data with cryptographic structure, and "Cipher to plaintext" operations that do the reverse.

P2C : sign, encrypt , digest C2P : verify, decrypt

The difference is this: P2C operations can meaningfully be done with many different choices of parameters. C2P operations can only be done with a specific set of parameters. Both of these create problems for developers. For P2C operations, the developer must choose how to set multiple parameters, choices that are likely not obvious to someone not skilled in the art. For C2P operations, the developer needs to make sure that they keep all the relevant parameters together with protected information.


So we have two problems: P2C: How to help developers make good choices ? C2P: How to help developers keep ciphertext associated to parameters ?

2. What would a solution look like?

On the face of it, the P2C problem -- choosing parameters -- seems easy to solve. If there are multiple valid sets of parameters, just have the browser / API implementation make the choice on behalf of the developer.

However, this exacerbates the C2P problem, because there are now many ways for the ciphertext to be separated from its parameters. If a web app does not store the parameters with which the ciphertext was computed (relying on the browser's defaults), then if the browser changes defaults, then the app will be unable to decrypt the ciphertext (or validate the signature). Even if the app stores the parameters, then it needs to make sure that the ciphertext is always associated with the correct parameters; the app cannot, for example, send the ciphertext for storage on a server, but not the parameters.

So in order to solve the P2C problem, we also need to solve the C2P problem. Namely, we need to make it easy by default for apps to keep parameters and ciphertext together. In API terms, that would seem to indicate that the results of a crypto operation should be provided as an object that contains all the relevant parameters (as indeed, CryptoOperation already does). In addition, it would be helpful if this object had a default serialization, to address the issue of parameters getting lost when the object is stored or sent someplace else.

This gives us two solutions to match the two problems:

P2C: Provide browser-chosen defaults C2P: Provide results in an object with parameters and a serialization

These don't prevent developers from running into problems -- choosing bad IVs, or deleting default parameters from the object -- but it encourages a default life-cycle that should be problem free:

  • Process plaintext, get ciphertext+parameters
  • Store ciphertext+parameters
  • Process ciphertext+parameters, get plaintext

These solutions also don’t get in the way of more advanced developers. You can still specify all the parameters, and still use whatever parts of the object you want.

Thoughts on a High-Level WebCrypto API (By Richard Barnes, BBN)

  • Goals

Allow all of the same basic operations as low-level (enc/dec/sig/ver/dig)

Plaintext format allows strings as well as ABV

Ciphertext format has a natural serialization (Ideally, JSON.stringify() to JOSE)

Parameters should have high level of auto-generation

"Encrypt" and "sign" functions can handle key wrapping

Promises-style asynchronous API


  • Use cases

Encrypt: Plaintext -> JWE ... to a public key ... to a symmetric key ... directly (no key wrapping)

Sign: Plaintext -> JWS ... under a public key ... with a symmetric key ... directly (no key wrapping)

Decrypt JWE

Verify JWS


  • Key management functions

Generate RSA key pair

Generate [EC]DH key pair

Generate secret key

Import key (JWE -> browser)

Export key (browser -> JWE)


  • Examples

// Choose an algorithm and make up a key

window.crypto.encrypt("message");

// Choose an algorithm, make up a key, and wrap it

window.crypto.encrypt("message", { to: recipientKey });

// Specify everything

window.crypt.encrypt("message", {

alg: { name: "AES-CBC", iv: "..." },

key: { kid: "8FB07080-950F-44E1-9D79-5A59A923385D" },

to: { n: "...", e: "..." }

});

// Decrypt a JWE

window.crypto.decrypt(jwe);

// Verify a JWS

window.crypto.verify(jws);


Notional IDL

dictionary Dictionary {};

typedef (ArrayBufferView or DOMString or Dictionary) Plaintext;

dictionary JoseObject {

Algorithm algorithm;

Key key;

DOMString data;

DOMString signature;

};

/* TODO: EncryptOptions, SignOptions */

interface Crypto {

CryptoPromise encrypt(Plaintext plaintext, EncryptOptions options);

CryptoPromise sign(Plaintext plaintext,SignOptions options);

PlaintextPromise decrypt(JoseObject encrypted);

PlaintextPromise verify(JoseObject signed);

PlaintextPromise digest(Plaintext plaintext);

  /* TODO: Key operations */    

}