Re: On Crypto API Safety in the Hands of Unskilled Developers


I thought Richard's piece was well written, made some good points and was
clearly targeted at the low-level API on which we are working. His
suggested remediation for the problems is straightforward. IMHO, at the
very least, it deserves a more considered response.


On Thu, Mar 28, 2013 at 8:39 AM, Ryan Sleevi <> wrote:

> Thank you for your description of a high-level API.
> At this time, the WG is pursuing a low-level API.
> On Mar 28, 2013 8:21 AM, "Richard Barnes" <> wrote:
>> The SubtleCrypto thread reminded me that I'd been meaning to send out
>> some notes I wrote down about unskilled developers.
>> Brief essay follows.  Comments welcome.
>> --Richard
>> On Crypto API Safety in the Hands of Unskilled Developers
>> =========================================================
>> I. What is the problem (general)?
>> ---------------------------------
>> The current API's approach of exposing unmitigated complexity to the
>> developer -- no defaults, no help from the browser -- is only plausible if
>> we assume that the only people who will use the API are experienced
>> cryptographers.  This assumption is clearly not true.  Any API that is
>> supplied in the DOM will be exposed to, and get used by, a much wider
>> variety of developers than we ever intend.
>> That's true of any DOM API, whether it's crypto, geolocation, canvas,
>> etc.  But crypto is special.
>> -- Bad crypto design leads to worse consequences
>> -- Bad crypto design is hard to detect
>> The whole point of having a crypto API is to protect sensitive things.
>>  So by definition, if you screw up your usage of the crypto API, you are
>> exposing sensitive things.  Moreover, if this happens, you are likely not
>> to notice it.  If you screw up your WebGL rendering code, things will look
>> bad.  If you re-use the same nonce twice in GCM, nothing is obviously
>> different.
>> So in its current state, the API makes it likely for bad things to
>> happen.  It would be irresponsible of this group to release an API in this
>> state.  We need to think seriously about how to make the default mode of
>> the API less likely to lead to pain, while still allowing for full
>> generality.
>> Think of this like consumer protection.  You can't ship a lawn mower that
>> doesn't have a guard around the blade.  Someone can buy a lawn mower, take
>> off the guard, and use the motor and blade in new and creative ways, at the
>> risk of injuring himself.  Even if someone isn't doing something advanced,
>> they can still stick their hand under the guard and get cut.  But by
>> default, in most use cases, the lawn mower is safe to use.
>> II. What is the problem (specific)?
>> -----------------------------------
>> 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       C2P
>> -----------------
>> sign      verify
>> encrypt   decrypt
>> digest
>> 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
>> III. 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.

Received on Thursday, 28 March 2013 15:42:50 UTC