You've included a SHA-256 hash function, but not an HMAC-SHA-256 function.
Having looked at many, many webapps as a pentester, I can assure that 99% of folks will do message authentication insecurely without better API support than a raw hash function.
They will: (a) create insecure constructions using secret prefix or secret suffix concatenations instead of implementing real HMAC, and then (b) they will leak timing information during verification
I would propose the following APIs: (if you only support SHA256 and have no plans to implement other algorithms)
hmac: {
createHMAC: function (plaintext, key, function callback(mac){ }) { }
verifyHMAC: function(plaintext, key, receivedMac, function callback(booleanVerified){ }){ }
}
Where verifyHMAC implements double-HMAC verification to prevent timing leakage as described here:
http://www.isecpartners.com/blog/2011/2/18/double-hmac-verification.html
Adding algorithm setters as is done for the symmetric functions would allow agility to move to, e.g. SHA3 in the future when it is defined.
-Brad Hill
-----Original Message-----
From: public-web-security-request@w3.org [mailto:public-web-security-request@w3.org] On Behalf Of David Dahl
Sent: Thursday, June 02, 2011 6:46 AM
To: public-web-security@w3.org
Subject: Request for feedback: DOMCrypt API proposal
Hello public-web-security members,
(I wanted to post this proposed draft spec for the DOMCrypt API ( https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest ) to this list - if there is a more fitting mailing list, please let me know)
I recently posted this draft spec for a crypto API for browsers to the whatwg (see: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031741.html) and wanted to get feedback from W3C as well.
Privacy and user control on the web is of utter importance. Tracking, unauthorized user data aggregation and personal information breaches are becoming so commonplace you see a new headline almost daily. (It seems).
We need crypto APIs in browsers to allow developers to create more secure communications tools and web applications that don’t have to implicitly trust the server, among other use cases.
The DOMCrypt API is a good start, and more feedback and discussion will really help round out how all of this should work – as well as how it can work in any browser that will support such an API.
This API will provide each web browser window with a ‘cipher’ property[1] that facilitates:
asymmetric encryption key pair generation
public key encryption
public key decryption
symmetric encryption
signature generation
signature verification
hashing
easy public key discovery via meta tags or an ‘addressbookentry’ tag
[1] There is a bit of discussion around adding this API to window.navigator or consolidation within window.crypto
I have created a Firefox extension that implements most of the above, and am working on an experimental patch that integrates this API into Firefox.
The project originated in an extension I wrote, the home page is here: http://domcrypt.org
The source code for the extension is here: https://github.com/daviddahl/domcrypt
The Mozilla bugs are here:
https://bugzilla.mozilla.org/show_bug.cgi?id=649154
https://bugzilla.mozilla.org/show_bug.cgi?id=657432
Firefox "feature wiki page": https://wiki.mozilla.org/Privacy/Features/DOMCryptAPI
You can test the API by installing the extension hosted at domcrypt.org, and going to http://domcrypt.org
A recent blog post updating all of this is posted here: http://monocleglobe..wordpress.com/2011/06/01/domcrypt-update-2011-06-01/
The API:
window.cipher = {
// Public Key API
pk: {
set algorithm(algorithm){ },
get algorithm(){ },
// Generate a keypair and then execute the callback function
generateKeypair: function ( function callback( aPublicKey ) { } ) { },
// encrypt a plainText
encrypt: function ( plainText, function callback (cipherMessageObject) ) { } ) { },
// 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 ) { }) { }
},
// Symmetric Crypto API
sym: {
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 ) { }) { },
},
// hashing
hash: {
SHA256: function (function callback (hash){}) { }
}
}
Your feedback and criticism will be invaluable.
Best regards,
David Dahl
Firefox Engineer, Mozilla Corp.