Privacy/Features/DOMCryptAPISpec/Latest: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(Fix another supplemental)
 
(44 intermediate revisions by 5 users not shown)
Line 1: Line 1:
= DOMCrypt 'window.cipher' Specification =
= DOMCrypt Specification =


;DRAFT
;DRAFT


;Version 0.1
;Version 0.4
 
;Updated 2011-07-26


; Author: David Dahl <ddahl@mozilla.com>
; Author: David Dahl <ddahl@mozilla.com>
; Author: Adam Barth <adam@adambarth.com>


== Introduction ==
== Introduction ==


This document describes a proposed Javascript Cryptography API available in web browsers to allow any web page script the ability to generate asymmetric key pairs, encrypt, decrypt, sign, verify, hash data ( via a variety of algorithms ) as well as the discovery and persistence of a contact's public key.
This document describes a proposed Javascript Cryptography API available in web browsers to allow any web page script the ability to generate asymmetric key pairs, encrypt, decrypt (asymmetric and symmetric crypto), sign, verify, HMAC, and hash data ( via a variety of algorithms ).
 
=== W3C Web Cryptography Working Group Charter ===
* The W3C is using the DOMCrypt API as the "strawman" API
** http://www.w3.org/2011/11/webcryptography-charter.html


== Terms ==
== Terms ==
Line 17: Line 24:


; window.cipher
; window.cipher
: The proposed window property name for this API
: The now '''deprecated''' proposed window property name for this API
 
; window.mozCrypto
: The temporary window property used to distinguish this new API from the current window.crypto property (used in the extension code and the current Gecko patches). The consensus so far is to add this API to the window.crypto property


; cipher Configuration
; window.crypto
: A JSON object that stores the user's private key and public key
: The existing DOM property where this API should be integrated


; Key Pair
; Key Pair
: An asymmetric pair of encryption keys. A Public Key which is used by others to encrypted data for you to decrypt with your Private Key
: An asymmetric pair of encryption keys. A Public Key which is used by others to encrypted data for you to decrypt with your Private Key. Key pairs are bound to the origin


; Public Key
; Public Key
Line 31: Line 41:
: The private half of an asymmetric key pair
: The private half of an asymmetric key pair


; cipherAddressbook or Addressbook
== Browser Window property WebIDL ==
: A JSON object containing a user's contact's public key. This is also a term used to avoid such cryptography lingo as 'key', 'key ring'


; AddressbookEntry
;window.mozCrypto<br>
: A JSON object that contains a contact's public key. The addressbook and AddressbookEntry nomenclature is used to simplify the way refer to public keys and key rings. e.g.: I need Natasha's AddressbookEntry in order to send her a private message (and she will need my AddressbookEntry to reply).


; Symmetric Key
All windows will have this property (in the current implementation) for the time being as this API is hashed out.
: an encryption key used for symmetric encryption


== Objects ==
The property is namespaced in order to provide future capabilities.


Note: Object definitions below are written in JSON.
<pre class="brush:js;toolbar:false;">
supplemental interface Crypto {
  readonly attribute CryptoPk pk;
  readonly attribute CryptoSign sign;
};


;cipherConfiguration
[Constructor(DOMString algorithm)]
interface CryptoHash {
  void append(ArrayBuffer data);
  ArrayBuffer finish();
};


A JSON Object which labels the Key Pairs, staring with a "default" Key Pair. This allows for multiple Key Pairs in the future.
[Constructor(DOMString algorithm, ArrayBuffer key)]
interface CryptoHmac {
  void append(ArrayBuffer data);
  ArrayBuffer finish();
};


{
callback interface GenerateKeypairCallback {
  "default": {
   void onsuccess(ArrayBuffer keyID, ArrayBuffer pubKey);
    "created"   : 1305140629979,
};
    "privKey"  : <BASE64 ENCODEDED PRIVATE KEY>,
    "pubKey"    : <BASE64 ENCODEDED PUBLIC KEY>,
    "salt"      : <ENCODED or ENCRYPTED Salt>,
    "iv"        : <ENCODED or ENCRYPTED IV>,
    "algorithm" : "AES_256_CBC",
  }


;cipherAddressbook
callback interface GetPublicKeyCallback {
  void onsuccess(ArrayBuffer pubKey);
};


The JSON object containing a user's contact's Public Keys
callback interface PKEncryptCallback {
   [
   void onsuccess(ArrayBuffer message);
    {
};
      "id"      : <a unique id, e.g: an email address>,
      "handle"  : "natasha",
      "domain"  : "domcrypt.org",
      "pubKey"  : <BASE64 ENCODED PUBLIC KEY>,
      "created" : 1305140629979,
    },
  ]


== Browser Window property  ==
callback interface PKDecryptCallback {
  void onsuccess(ArrayBuffer plainText);
};


;window.cipher<br>
interface CryptoPk {
  void generateKeypair(DOMString algorithm, GenerateKeypairCallback callback, boolean signingKeypair);
  void getPublicKey(GetPublicKeyCallback callback);
  void encrypt(ArrayBuffer plainText, ArrayBuffer keyID, PKEncryptCallback callback);
  void decrypt(ArrayBuffer message, ArrayBuffer keyID, PKDecryptCallback callback);
};


All web pages will have this property. The property is namespaced in order to provide future capabilities. The current design is asynchronous and looks like this: <br>
callback interface SignCallback {
<pre class="brush:js;toolbar:false;">
  void onsuccess(ArrayBuffer signature);
{
};
  pk: {
    // Public Key API
   
    set algorithm(algorithm){ },
   
    get algorithm(){ },


    // Generate a keypair and then execute the callback function
callback interface VerifyCallback {
    generateKeypair: function ( function callback( aPublicKey ) { } ) {  },
  void onsuccess(boolean verified);
};


    // encrypt a plainText
interface CryptoSign {
    encrypt: function ( plainText, function callback (cipherMessageObject) ) { } ) {  },
  void sign(ArrayBuffer keyID, ArrayBuffer plainText, PKSignCallback callback);
 
  void verify(ArrayBuffer signature, ArrayBuffer pubKey, ArrayBuffer plainText, PKVerifyCallback callback);
    // decrypt a cipherMessage
};
    decrypt: function ( cipherMessageObject, function callback ( plainText ) { } ) {  },    
 
    // sign a message
    sign: function ( plainText, function callback ( signature ) { } ) {  },     
 
    // verify a signature
    verify: function ( signature, plainText, function callback ( boolean ) { } ) {  },
 
    // get the JSON cipherAddressbook
    get addressbook() {},
   
    // make changes to the addressbook
    saveAddressbook: function (JSONObject, function callback ( addresssbook ) { }) {  }
  },
 
  sym: {
    // Symmetric Crypto API
 
    get algorithm(), 
 
    set algorithm(algorithm),
   
    // create a new symmetric key
    generateKey: function (function callback ( key ){ }) {  },
   
    // encrypt some data
    encrypt: function (plainText, key, function callback( cipherText ){ }) {  },
   
    // decrypt some data
    decrypt: function (cipherText, key, function callback( plainText ) { }) {  },
  },
 
  hash: {
    SHA256: function (function callback (hash){}) {  }
  }
}
</pre>
</pre>


== PublicKey discovery  ==
== Notes ==


A user discovers public keys (addressbook entries) in the markup of a web page as a meta tag. The browser alerts the user that an 'addressbookEntry' has been published. the user then has the option to save it to the cipherAddressbook
*Each origin will only have access to the asymmetric private key generated for it. This will minimize  the need for any kind of access control dialog for key usage.
* All the inputs and outputs should be raw, unformatted ArrayBuffers, letting higher-level pure JS wrappers deal with conversion to application data formats until we understand better what higher-level formats would be useful


;addressbookEntry
== Possible Additions ==
<pre class="brush:html;toolbar:false;">
<meta name="addressbook-entry" pubkey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vW1laRyBkIfdeB2GQT+rz4dRwYUMtQJQ4Z8/QJCQj5qFuYKqcUn+8UssedWMjygRME1Eamcv5X5HLvphYMaRufk4PvKXLNq0Xh7cmNLcpQT639v+RjWpvHNWsdtYfd80nKCf1S46TlbH2/aw/+tcdLdj8MOTDtzII2oCcXU8B8PXNf49rcNMv8KagjC6LMQDrgvmZ56T1J3wHtQAH/QXGvh4WjQc2sWC/V+2xGkQL4+4yeP7STJBQXKmmqanExsqmwii1rV0Rd2GQnJRaSj+56HMDbZkLnZsxJExul5vu6ec+nBfACxWDMVCeVWbYxBpfURgC5nDsznkgT5VhXOJwIDAQAB",


          handle="natasha",
One possible addition we might consider is providing the web site with a secure mechanism having the user confirm a transaction. For example, a bank web site might wish to have the user sign a statement authorizing the transfer of funds from one account to another. Unlike the DOMCrypt APIs described above, this API involves interacting with the user to achieve non-repudiation:
          domain="droplettr.com"
<pre class="brush:js;toolbar:false;">
          date="1298322911812",
supplemental interface CryptoSign {
          algorithm="AES_256_CBC"&gt;
  void signWithUserConfirmation(in ArrayBuffer keyID, in DOMString description, in ArrayBuffer data, in PKSignCallback callback);
 
};
</meta>
</pre>  
</pre>
The signWithUserConfirmation method causes the user agent to display some user interface element containing the human-readable description. If the user confirms the description, the user agent with sign both the human-readable description and the binary data with the key designated by the keyId and supply the signature to the caller via the callback. There are still many details to work out, such as the format of the signed message, but this description is a starting point for discussion.
 
== Notes ==


; window.mozCipher is the proposed experimental, mozilla-prefixed window property name for this API
to deploy this feature to production level, we have to consider following issues.  


; The implementation should allow users to whitelist domains and pages which are authorized to use this API - especially in regards to creating keypairs and getting the user's addressbook
*is passphase of private key safely entered?. means the confirmation screen need anti-keylogger mechanism.
*is browser sandbox safe? even on the user environment is compromized. (virus-infected?)
*co-operatable with requirements of security compliances (PCI, ISO27001...)


== References  ==
== References  ==


*DOMCrypt: http://domcrypt.org  
*DOMCrypt: http://domcrypt.org  
*cipher mozilla bugs:  
*DOMCrypt Mozilla bugs:  
**https://bugzilla.mozilla.org/show_bug.cgi?id=649154  
**https://bugzilla.mozilla.org/show_bug.cgi?id=649154  
**https://bugzilla.mozilla.org/show_bug.cgi?id=657432
**https://bugzilla.mozilla.org/show_bug.cgi?id=657432
*WHAT-WG mailing list thread: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031741.html
*DOMCrypt WebKit bug:
*WHAT-WG mailing list summary: http://etherpad.mozilla.com:9000/DOMCrypt-discussion
**https://bugs.webkit.org/show_bug.cgi?id=62010
<br>
 
*WHATWG mailing list thread: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031741.html
*W3C mailing list thread: http://lists.w3.org/Archives/Public/public-web-security/2011Jun/0000.html
*Mailing lists summarized http://etherpad.mozilla.com:9000/DOMCrypt-discussion
 
== Meetings ==
 
* 2011-07-14, at Mozilla, Mountain View, CA [[Privacy/Features/DOMCryptAPISpec/Meeting-2011-07-14]]

Latest revision as of 13:25, 15 February 2012

DOMCrypt Specification

DRAFT
Version 0.4
Updated 2011-07-26
Author
David Dahl <ddahl@mozilla.com>
Author
Adam Barth <adam@adambarth.com>

Introduction

This document describes a proposed Javascript Cryptography API available in web browsers to allow any web page script the ability to generate asymmetric key pairs, encrypt, decrypt (asymmetric and symmetric crypto), sign, verify, HMAC, and hash data ( via a variety of algorithms ).

W3C Web Cryptography Working Group Charter

Terms

DOMCrypt
A generic label for the entire crypto API originating in the open source project 'DOMCrypt'
window.cipher
The now deprecated proposed window property name for this API
window.mozCrypto
The temporary window property used to distinguish this new API from the current window.crypto property (used in the extension code and the current Gecko patches). The consensus so far is to add this API to the window.crypto property
window.crypto
The existing DOM property where this API should be integrated
Key Pair
An asymmetric pair of encryption keys. A Public Key which is used by others to encrypted data for you to decrypt with your Private Key. Key pairs are bound to the origin
Public Key
The public half of an asymmetric key pair
Private Key
The private half of an asymmetric key pair

Browser Window property WebIDL

window.mozCrypto

All windows will have this property (in the current implementation) for the time being as this API is hashed out.

The property is namespaced in order to provide future capabilities.

 
supplemental interface Crypto {
  readonly attribute CryptoPk pk;
  readonly attribute CryptoSign sign;
};

[Constructor(DOMString algorithm)]
interface CryptoHash {
  void append(ArrayBuffer data);
  ArrayBuffer finish();
};

[Constructor(DOMString algorithm, ArrayBuffer key)]
interface CryptoHmac {
  void append(ArrayBuffer data);
  ArrayBuffer finish();
};

callback interface GenerateKeypairCallback {
  void onsuccess(ArrayBuffer keyID, ArrayBuffer pubKey);
};

callback interface GetPublicKeyCallback {
  void onsuccess(ArrayBuffer pubKey);
};

callback interface PKEncryptCallback {
  void onsuccess(ArrayBuffer message);
};

callback interface PKDecryptCallback {
  void onsuccess(ArrayBuffer plainText);
};

interface CryptoPk {
  void generateKeypair(DOMString algorithm, GenerateKeypairCallback callback, boolean signingKeypair);
  void getPublicKey(GetPublicKeyCallback callback);
  void encrypt(ArrayBuffer plainText, ArrayBuffer keyID, PKEncryptCallback callback);
  void decrypt(ArrayBuffer message, ArrayBuffer keyID, PKDecryptCallback callback);
};

callback interface SignCallback {
  void onsuccess(ArrayBuffer signature);
};

callback interface VerifyCallback {
  void onsuccess(boolean verified);
};

interface CryptoSign {
  void sign(ArrayBuffer keyID, ArrayBuffer plainText, PKSignCallback callback);
  void verify(ArrayBuffer signature, ArrayBuffer pubKey, ArrayBuffer plainText, PKVerifyCallback callback);
};

Notes

  • Each origin will only have access to the asymmetric private key generated for it. This will minimize the need for any kind of access control dialog for key usage.
  • All the inputs and outputs should be raw, unformatted ArrayBuffers, letting higher-level pure JS wrappers deal with conversion to application data formats until we understand better what higher-level formats would be useful

Possible Additions

One possible addition we might consider is providing the web site with a secure mechanism having the user confirm a transaction. For example, a bank web site might wish to have the user sign a statement authorizing the transfer of funds from one account to another. Unlike the DOMCrypt APIs described above, this API involves interacting with the user to achieve non-repudiation:

 
supplemental interface CryptoSign {
  void signWithUserConfirmation(in ArrayBuffer keyID, in DOMString description, in ArrayBuffer data, in PKSignCallback callback); 
};

The signWithUserConfirmation method causes the user agent to display some user interface element containing the human-readable description. If the user confirms the description, the user agent with sign both the human-readable description and the binary data with the key designated by the keyId and supply the signature to the caller via the callback. There are still many details to work out, such as the format of the signed message, but this description is a starting point for discussion.

to deploy this feature to production level, we have to consider following issues.

  • is passphase of private key safely entered?. means the confirmation screen need anti-keylogger mechanism.
  • is browser sandbox safe? even on the user environment is compromized. (virus-infected?)
  • co-operatable with requirements of security compliances (PCI, ISO27001...)

References

Meetings