securing todomvc using the web cryptography api

99
Securing TodoMVC Using the Web Cryptography API Kevin Hakanson 12 September 2014

Upload: kevin-hakanson

Post on 05-Dec-2014

156 views

Category:

Technology


4 download

DESCRIPTION

The open source TodoMVC project implements a Todo application using popular JavaScript MV* frameworks. Some of the implementations add support for compile to JavaScript languages, module loaders and real time backends. This presentation will demonstrate a TodoMVC implementation which adds support for the forthcoming W3C Web Cryptography API, as well as review some key cryptographic concepts and definitions. Instead of storing the Todo list as plaintext in localStorage, this "secure" TodoMVC implementation encrypts Todos using a password derived key. The PBKDF2 algorithm is used for the deriveKey operation, with getRandomValues generating a cryptographically random salt. The importKey method sets up usage of AES-CBC for both encrypt and decrypt operations. The final solution helps address item "A6-Sensitive Data Exposure" from the OWASP Top 10. With the Web Cryptography API being a recommendation in 2014, any Q&A time will likely include browser implementations and limitations, and whether JavaScript cryptography adds any value.

TRANSCRIPT

Page 1: Securing TodoMVC Using the Web Cryptography API

Securing TodoMVCUsing the

Web Cryptography API

Kevin Hakanson12 September 2014

Page 2: Securing TodoMVC Using the Web Cryptography API

Kevin Hakanson

@hakanson

+KevinHakanson

hakanson

Page 3: Securing TodoMVC Using the Web Cryptography API

Project which offers the same Todo application implemented using MV* concepts in most of the popular JavaScript MV* frameworks of today.

http://todomvc.com/https://github.com/tastejs/todomvc

Page 4: Securing TodoMVC Using the Web Cryptography API
Page 5: Securing TodoMVC Using the Web Cryptography API

Today's Session "todos"

● Review some cryptography concepts● Look at the Web Cryptography API● Combine these to secure TodoMVC

Page 6: Securing TodoMVC Using the Web Cryptography API

Supporting Materials

(if you want to follow along)

Presentation and Source Codehttps://github.com/hakanson/todomvc-jquery-webcryptoapi

Demohttps://hakanson.github.io/todomvc-jquery-webcryptoapi

Page 7: Securing TodoMVC Using the Web Cryptography API

Why?

Page 8: Securing TodoMVC Using the Web Cryptography API

TodoMVC Uses localStorage

Chrome keeps localStorage in an SQLite file:OS X: ~/Library/Application Support/Google/Chrome/Default/Local StorageWindows: %HOMEPATH%\AppData\Local\Google\Chrome\User Data\Default\Local Storage

$ sqlite3 http_todomvc.com_0.localstorage

sqlite> select * from ItemTable;

todos-jquery|[{"id":"c8f7b7e1-88bf-451b-8aff-04c9ac2544aa","title":"secure using Web Cryptography API","completed":false}]

Page 9: Securing TodoMVC Using the Web Cryptography API

OWASP Top 10 2013

● A1-Injection● A2-Broken Authentication and Session Management● A3-Cross-Site Scripting (XSS)● A4-Insecure Direct Object References● A5-Security Misconfiguration● A6-Sensitive Data Exposure● A7-Missing Function Level Action Control● A8-Cross-Site Request Forgery (CSRF)● A9-Using Components with Known Vulnerabilities● A10-Unvalidated Redirects and Forwards

https://www.owasp.org/index.php/Top_10_2013

Page 10: Securing TodoMVC Using the Web Cryptography API

A6-Sensitive Data Exposure

Covers sensitive data protection from the moment sensitive data is provided by the user, sent to and stored within the application, and then sent back to the browser again.

Page 11: Securing TodoMVC Using the Web Cryptography API

A6-Sensitive Data Exposure

Am I Vulnerable To 'Sensitive Data Exposure'?

1. Is any of this data stored in clear text long term, including backups of this data?

2. …3. …4. …5. …

https://www.owasp.org/index.php/Top_10_2013-A6

Page 12: Securing TodoMVC Using the Web Cryptography API

Acceptance Criteria

● Enter password before accessing "todos"● Data encrypted "at rest" in localStorage

Page 13: Securing TodoMVC Using the Web Cryptography API

How?

Page 14: Securing TodoMVC Using the Web Cryptography API

W3C Web Cryptography API

This specification describes a JavaScript API for performing basic cryptographic operations in web applications, such as hashing, signature generation and verification, and encryption and decryption.

http://www.w3.org/TR/WebCryptoAPI/

Page 15: Securing TodoMVC Using the Web Cryptography API

WebCryptoAPI Use Cases

● Multi-factor Authentication● Protected Document Exchange● Cloud Storage● Document Signing● Data Integrity Protection● Secure Messaging● Javascript Object Signing and Encryption

(JOSE)

http://www.w3.org/TR/WebCryptoAPI/#use-cases

Page 16: Securing TodoMVC Using the Web Cryptography API

SubtleCrypto Interface

● Provides a set of methods for dealing with low-level cryptographic primitives and algorithms.

● Named SubtleCrypto to reflect the fact that many of these algorithms have subtle usage requirements in order to provide the required algorithmic security guarantees.

Page 17: Securing TodoMVC Using the Web Cryptography API

Web Cryptography Working Group

Key Dates○ April 2012: Group Formation

○ March 2014: Last Call Working Draft

○ ????: Expected Candidate Recommendation

○ ????: Expected Proposed Recommendation

○ 2015: Expected Recommendation

http://www.w3.org/2012/webcrypto/Overview.html

Page 18: Securing TodoMVC Using the Web Cryptography API

Where?(Browser Support)

Page 19: Securing TodoMVC Using the Web Cryptography API

Chromium Dashboard

Web Crypto API

Implementation StatusEnabled by default in desktop Chrome 37 (launch bug)Available in Chrome for Android release 37.

Consensus & Standardization● Firefox: In development● Internet Explorer: In development● Opera: Shipped in release 24● Opera for Android: Shipped in release 24● Safari: In development● Web Developers: Mixed signals

Page 20: Securing TodoMVC Using the Web Cryptography API

http://caniuse.com/#search=Web Cryptography

Page 21: Securing TodoMVC Using the Web Cryptography API

IE Platform Status

Web Crypto API

Note: IE11 implementation based on spec before change from CryptoOperation to Promise based API

Page 22: Securing TodoMVC Using the Web Cryptography API

Promises/A+

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled.

Page 23: Securing TodoMVC Using the Web Cryptography API

Chromium Dashboard

Promises (ES6)

Implementation StatusEnabled by default in desktop Chrome 32 (launch bug)Available in Chrome for Android release 32.

Consensus & Standardization● Firefox: Shipped● Internet Explorer: Public support● Opera: Shipped in release 19● Opera for Android: Shipped in release 19● Safari: In development● Web Developers: Mixed signals

Page 24: Securing TodoMVC Using the Web Cryptography API

Microsoft Research JavaScript Cryptography Library

● The algorithms are exposed via the W3C WebCrypto interface, and are tested against the Internet Explorer 11 implementation of that interface.

● This library is under active development. Future updates to this library may change the programming interfaces.

Date Published: 17 June 2014

Page 25: Securing TodoMVC Using the Web Cryptography API

But...

Page 26: Securing TodoMVC Using the Web Cryptography API

Javascript Cryptography Considered Harmful (circa 2010)

● Opinion on browser Javascript cryptography○ "no reliable way for any piece of Javascript code to

verify its execution environment"○ "can't outsource random number generation in a

cryptosystem"○ "practically no value to doing crypto in Javascript

once you add SSL to the mix"○ "store the key on that server [and] documents there"http://www.matasano.com/articles/javascript-cryptography/

● Didn't consider the "offline" user experience

Page 27: Securing TodoMVC Using the Web Cryptography API

Host-Proof Hosting

● In A Blink○ Sketch: Locked inside data cloud, key at browser.

● Solution○ Host sensitive data in encrypted form, so that clients

can only access and manipulate it by providing a pass-phrase which is never transmitted to the server.

○ All encryption and decryption takes place inside the browser itself.

http://ajaxpatterns.org/Host-Proof_Hosting (July 2005)

Page 28: Securing TodoMVC Using the Web Cryptography API

Host-Proof Hosting "Requirements"

● Secure transport mechanism (HTTPS).

● Trust provider that hosts web application and serves HTML and JavaScript resources.

● Defend against and accept risk of script injection (XSS) threat.○ However, unauthorized access by hackers only

attacks users who access the application while infected, and not the entire persisted data store.

Page 29: Securing TodoMVC Using the Web Cryptography API

My "Requirement"

● Avoid proving "Schneier's Law"

○ Anyone can invent a security system that he himself cannot break.

Page 30: Securing TodoMVC Using the Web Cryptography API

What?(concepts)

Page 31: Securing TodoMVC Using the Web Cryptography API

Glossary

Glossary of Key Information Security Terms

http://nvlpubs.nist.gov/nistpubs/ir/2013/NIST.IR.7298r2.pdf

SOURCE: NISTIR 7298

Page 32: Securing TodoMVC Using the Web Cryptography API

Cryptography

The discipline that embodies principles, means, and methods for providing information security, including confidentiality, data integrity, non-repudiation, and authenticity.

SOURCE: SP 800-21

Page 33: Securing TodoMVC Using the Web Cryptography API

Pseudorandom number generator (PRNG)

An algorithm that produces a sequence of bits that are uniquely determined from an initial value called a seed. The output of the PRNG “appears” to be random.

A cryptographic PRNG has the additional property that the output is unpredictable, given that the seed is not known.

SOURCE: CNSSI-4009

Page 34: Securing TodoMVC Using the Web Cryptography API

crypto.getRandomValues()

If you provide an integer-based TypedArray, the function is going fill the array with cryptographically random numbers.

var buf = new Uint8Array(32);

window.crypto.getRandomValues(buf);

https://developer.mozilla.org/en-US/docs/DOM/window.crypto.getRandomValueshttp://msdn.microsoft.com/en-us/library/ie/dn302324(v=vs.85).aspx

Page 35: Securing TodoMVC Using the Web Cryptography API

Cryptographic Hash Function

A function that maps a bit string of arbitrary length to a fixed length bit string.

Approved hash functions satisfy the following properties:

● One-way ● Collision resistant

SOURCE: SP 800-21

Page 36: Securing TodoMVC Using the Web Cryptography API

Message Digest

The result of applying a hash function to a message. Also known as a “hash value” or “hash output”.

SOURCE: SP 800-107

Page 37: Securing TodoMVC Using the Web Cryptography API

OpenSSL Command Line

$ echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha256

(stdin)= d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592

Page 38: Securing TodoMVC Using the Web Cryptography API

QUnit TestQUnit.test( 'SHA-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

sha256Hash : 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592'

};

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

assert.promise( crypto.subtle.digest( { name: 'sha-256' }, dataBuf )

.then( function (result) {

var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );

assert.equal( hash, testVector.sha256Hash );

}));

});

Page 39: Securing TodoMVC Using the Web Cryptography API

QUnit ExtensionQUnit.extend( QUnit.assert, {

promise: function ( promise ) {

var assert = this;

QUnit.stop();

promise.catch( function ( err ) {

assert.ok( false, err.message );

}).then( function ( ) {

QUnit.start();

});

}

});

Page 40: Securing TodoMVC Using the Web Cryptography API

ex: DOMExceptioncode: 9message: "WebCrypto is only supported over secure origins. See http://crbug.com/373032"name: "NotSupportedError"__proto__: DOMException

For example these are considered secure origins:● chrome-extension://xxx● https://xxx● wss://xxx● file://xxx● http://localhost/● http://127.0.0.1/

Whereas these are considered insecure:● http://foobar● ws://foobar

Page 41: Securing TodoMVC Using the Web Cryptography API

TextEncoder

Encoding APIScript API to allow encoding/decoding of strings from binary data.

Firefox 19https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder

Intent to Ship in Chrome 38Issue 243354: Implement Text Encoding API

Polyfillhttps://github.com/inexorabletash/text-encoding

Page 42: Securing TodoMVC Using the Web Cryptography API

$.Uint8Util

toHexString( buf : Uint8Array ) : string

fromHexString ( s : string ) : Uint8Array

(still looking for a better way)

Page 43: Securing TodoMVC Using the Web Cryptography API

$.WebCryptoAPI

Wrapper around:● crypto (WebCrypto spec)● msCrypto (IE11)● msrCrypto (Microsoft Research)● webkitSubtle (Webkit Nightly)

Implemented as jQuery Utility Plugin

Page 44: Securing TodoMVC Using the Web Cryptography API

Hash-based Message Authentication Code (HMAC)

A message authentication code that uses a cryptographic key in conjunction with a hash function.

SOURCE: FIPS 201; CNSSI-4009

Page 45: Securing TodoMVC Using the Web Cryptography API

Cryptographic Key

A parameter used in conjunction with a cryptographic algorithm that determines

● the transformation of plaintext data into ciphertext data, ● the transformation of ciphertext data into plaintext data, ● a digital signature computed from data,● ...

SOURCE: FIPS 140-2

Page 46: Securing TodoMVC Using the Web Cryptography API

Symmetric Key

A cryptographic key that is used to perform both the cryptographic operation and its inverse, for example to encrypt and decrypt, or create a message authentication code and to verify the code.

SOURCE: SP 800-63; CNSSI-4009

Page 47: Securing TodoMVC Using the Web Cryptography API

Digital Signature

The result of a cryptographic transformation of data which, when properly implemented, provides the services of:

1. origin authentication,2. data integrity, and3. signer non-repudiation.

SOURCE: FIPS 140-2

Page 48: Securing TodoMVC Using the Web Cryptography API

OpenSSL Command Line

$ echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha256 -hmac "key"

(stdin)= f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

Page 49: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'HMAC using SHA-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

key: 'key',

hash : 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'

};

var hmacSha256 = { name: 'hmac', hash: { name: 'sha-256' } };

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

var keyBuf = encoder.encode( testVector.key );

});

Page 50: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'HMAC using SHA-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

key: 'key',

hash : 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'

};

var hmacSha256 = { name: 'hmac', hash: { name: 'sha-256' } };

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

var keyBuf = encoder.encode( testVector.key );

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacSha256,

true, ['sign', 'verify'] )

.then( function ( keyResult ) {

}));

});

Page 51: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'HMAC using SHA-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

key: 'key',

hash : 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'

};

var hmacSha256 = { name: 'hmac', hash: { name: 'sha-256' } };

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

var keyBuf = encoder.encode( testVector.key );

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacSha256,

true, ['sign', 'verify'] )

.then( function ( keyResult ) {

return crypto.subtle.sign( hmacSha256, keyResult, dataBuf )

.then( function ( signResult ) {

var hash = $.Uint8Util.toHexString( new Uint8Array( signResult ) );

assert.equal( hash, testVector.hash );

})

}));

});

Page 52: Securing TodoMVC Using the Web Cryptography API

KJH-256 Hash

QUnit.test( 'KJH-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

};

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

assert.promise( crypto.subtle.digest( { name: 'kjh-256' }, dataBuf )

.then( function ( result ) {

var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );

assert.equal( hash, 'kjh' );

}));

});

Page 53: Securing TodoMVC Using the Web Cryptography API

Error ResultsIE 11

NotSupportedErrorChrome 37

Algorithm: Unrecognized nameFirefox 35

An invalid or illegal string was specifiedOpera 24

Algorithm: Unrecognized nameMSR Crypto 1.2

unsupported algorithmWebkit Nightly

NotSupportedError: DOM Exception 9

Page 54: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'HMAC using KJH-256', function ( assert ) {

var testVector = {

data: 'The quick brown fox jumps over the lazy dog',

key: 'key'

};

var encoder = new TextEncoder();

var dataBuf = encoder.encode( testVector.data );

var keyBuf = encoder.encode( testVector.key );

var hmacKjh256 = { name: 'hmac', hash: { name: 'kjh-256' } };

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacKjh256,

true, ['sign', 'verify'] )

.then( function ( keyResult ) {

return crypto.subtle.sign( hmacKjh256, keyResult, dataBuf )

.then( function ( signResult ) {

var hash = $.Uint8Util.toHexString( new Uint8Array( signResult ) );

assert.equal( hash, 'kjh' );

})

}));

});

Page 55: Securing TodoMVC Using the Web Cryptography API

Error ResultsIE 11

failed, expected argument to be truthy, was: falseChrome 37

HmacImportParams: hash: Algorithm: Unrecognized nameFirefox 35

An invalid or illegal string was specifiedOpera 24

HmacImportParams: hash: Algorithm: Unrecognized nameMSR Crypto 1.2

Error: unsupported hash alorithm (sha-224, sha-256, sha-384, sha-512)Webkit Nightly

NotSupportedError: DOM Exception 9

Page 56: Securing TodoMVC Using the Web Cryptography API
Page 57: Securing TodoMVC Using the Web Cryptography API

Cipher, Plaintext and Ciphertext

Cipher - Series of transformations that converts plaintext to ciphertext using the Cipher Key.

See Also: Inverse Cipher

SOURCE: FIPS 197

Page 58: Securing TodoMVC Using the Web Cryptography API

AES

The Advanced Encryption Standard specifies a U.S. government approved cryptographic algorithm that can be used to protect electronic data.

The AES algorithm is a symmetric block cipher that can encrypt (encipher) and decrypt (decipher) information.

SOURCE: FIPS 197

Page 59: Securing TodoMVC Using the Web Cryptography API

(CC BY 3.0) http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html

Page 60: Securing TodoMVC Using the Web Cryptography API

Initialization Vector (IV)

A vector used in defining the starting point of an encryption process within a cryptographic algorithm.

SOURCE: FIPS 140-2

Page 61: Securing TodoMVC Using the Web Cryptography API

OpenSSL Command Line

$ echo -n "Message" | openssl enc -aes256 -K 0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96 -iv 6C4C31BDAB7BAFD35B23691EC521E28D | xxd -p

23e5ebe72d99cf302c99183c05cf050a

Page 62: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'AES-CBC', function ( assert ) {

var testVector = {

plaintext: 'Message',

iv: '6C4C31BDAB7BAFD35B23691EC521E28D',

key: '0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96',

ciphertext: '23e5ebe72d99cf302c99183c05cf050a'

};

var encoder = new TextEncoder();

var decoder = new TextDecoder();

var buf = encoder.encode( testVector.plaintext );

var keyBuf = $.Uint8Util.fromHexString( testVector.key );

var ivBuf = $.Uint8Util.fromHexString( testVector.iv );

var aesCbc = { name: 'AES-CBC', iv: ivBuf };

// import key, encrypt, decrypt and compare

});

Page 63: Securing TodoMVC Using the Web Cryptography API

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' },

true, ['encrypt', 'decrypt'] )

.then( function ( encryptionKey ) {

}));

Page 64: Securing TodoMVC Using the Web Cryptography API

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' },

true, ['encrypt', 'decrypt'] )

.then( function ( encryptionKey ) {

return crypto.subtle.encrypt( aesCbc, encryptionKey, buf )

.then( function ( encryptResult ) {

var encryptBuf = new Uint8Array( encryptResult );

var ciphertext = $.Uint8Util.toHexString( encryptBuf );

assert.equal( ciphertext, testVector.ciphertext );

});

}));

Page 65: Securing TodoMVC Using the Web Cryptography API

assert.promise( crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' },

true, ['encrypt', 'decrypt'] )

.then( function ( encryptionKey ) {

return crypto.subtle.encrypt( aesCbc, encryptionKey, buf )

.then( function ( encryptResult ) {

var encryptBuf = new Uint8Array( encryptResult );

var ciphertext = $.Uint8Util.toHexString( encryptBuf );

assert.equal( ciphertext, testVector.ciphertext );

return crypto.subtle.decrypt( aesCbc, encryptionKey, encryptBuf )

.then( function ( decryptResult ) {

var plaintext = decoder.decode( new Uint8Array( decryptResult ) );

assert.equal( plaintext, testVector.plaintext );

});

});

}));

Page 66: Securing TodoMVC Using the Web Cryptography API

reduxchained vs. nested promises

Page 67: Securing TodoMVC Using the Web Cryptography API

function importKey () {

return crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' },

true, ['encrypt', 'decrypt'] )

}

function encrypt ( importedKey ) {

encryptionKey = importedKey;

return crypto.subtle.encrypt( aesCbc, encryptionKey, buf );

}

function decrypt ( encryptResult ) {

var encryptBuf = new Uint8Array( encryptResult );

var ciphertext = $.Uint8Util.toHexString( encryptBuf );

assert.equal( ciphertext, testVector.ciphertext );

return crypto.subtle.decrypt( aesCbc, encryptionKey, encryptBuf );

}

Page 68: Securing TodoMVC Using the Web Cryptography API

function compare ( decryptResult ) {

var plaintext = decoder.decode( new Uint8Array( decryptResult ) );

assert.equal( plaintext, testVector.plaintext );

}

assert.promise( importKey()

.then( encrypt )

.then( decrypt )

.then( compare );

);

Page 69: Securing TodoMVC Using the Web Cryptography API
Page 70: Securing TodoMVC Using the Web Cryptography API

Password-Based Key Derivation Functions (PBKDF)

● The randomness of cryptographic keys is essential for the security of cryptographic applications.

SOURCE: SP 800-132

Page 71: Securing TodoMVC Using the Web Cryptography API

Password-Based Key Derivation Functions (PBKDF)

● The randomness of cryptographic keys is essential for the security of cryptographic applications.

● Most user-chosen passwords have low entropy and weak randomness properties.○ shall not be used directly as cryptographic keys

SOURCE: SP 800-132

Page 72: Securing TodoMVC Using the Web Cryptography API

Password-Based Key Derivation Functions (PBKDF)

● The randomness of cryptographic keys is essential for the security of cryptographic applications.

● Most user-chosen passwords have low entropy and weak randomness properties.○ shall not be used directly as cryptographic keys

● KDFs are deterministic algorithms that are used to derive cryptographic keying material from a secret value, such as a password.

SOURCE: SP 800-132

Page 73: Securing TodoMVC Using the Web Cryptography API

Salt

A non-secret value that is used in a cryptographic process, usually to ensure that the results of computations for one instance cannot be reused by an Attacker.

SOURCE: SP 800-63; CNSSI-4009

Page 74: Securing TodoMVC Using the Web Cryptography API

PBKDF Specification

Input:P PasswordS SaltC Iteration countkLen Length of MK in bits; at most (232-1) x hLen

Parameter:PRF HMAC with an approved hash functionhlen Digest size of the hash function

Output:mk Master key

http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf

Page 75: Securing TodoMVC Using the Web Cryptography API

QUnit.test( 'PBKDF2', function ( assert ) {

var testVector = {

password : 'password',

salt: 'cf7488cd1e48e84990f51b3f121e161318ba2098aa6c993ded1012c955d5a3e8',

iterations: 100,

key: 'c12b2e03a08f3f0d23f3c4429c248c275a728814053a093835e803bc8e695b4e'

};

var alg = {

name: 'PBKDF2',

hash: 'SHA-1',

salt: $.Uint8Util.fromHexString( testVector.salt ),

iterations: testVector.iterations

};

// import key, derive bits and compare

});

Page 76: Securing TodoMVC Using the Web Cryptography API

var passwordBuf = decoder.decode( testVector.password );

assert.promise( crypto.subtle.importKey('raw', passwordBuf, 'PBKDF2',

false, ['deriveKey'])

.then(function ( keyResult ) {

}));

Page 77: Securing TodoMVC Using the Web Cryptography API

var passwordBuf = decoder.decode( testVector.password );

assert.promise( crypto.subtle.importKey('raw', passwordBuf, 'PBKDF2',

false, ['deriveKey'])

.then(function ( keyResult ) {

return crypto.subtle.deriveBits( alg, keyResult, 256 )

.then(function ( deriveResult ) {

var deriveBuf = new Uint8Array( deriveResult );

var key = $.Uint8Util.toHexString( deriveBuf );

assert.equal( key, testVector.key );

});

}));

Page 78: Securing TodoMVC Using the Web Cryptography API
Page 79: Securing TodoMVC Using the Web Cryptography API

Data Flow and Storage (expected)

● Salt = initial random● IV = initial random● Ciphertext = AES( todos, Key, IV )

Page 80: Securing TodoMVC Using the Web Cryptography API

Data Flow and Storage (actual)

● PBKDF2 only implemented in Firefox 33● Substitute HMAC to generate 256 bit key

○ (do not try this at home)

Page 81: Securing TodoMVC Using the Web Cryptography API

Set and Confirm Password

On first use, password must be established.

Page 82: Securing TodoMVC Using the Web Cryptography API

Password Entry Field

<header id="header">

<h1><span>secure</span> todos</h1>

<input id="new-todo"

placeholder="What needs to be done?"

class="hidden">

<input id="todo-password"

type="password"

placeholder="Enter Password"

autofocus

class="edit">

</header>

Page 83: Securing TodoMVC Using the Web Cryptography API

Render Password Entry Fieldrender: function () {

var todos, placeholder;

if (this.todos) {

this.$password.addClass('hidden');

// todos list rendering...

} else {

if (!cryptoStorage.initialized) {

placeholder = (this.$password.data('confirm') ?

'Confirm Password' : 'Set Password');

this.$password.attr('placeholder', placeholder);

}

this.$password.removeClass('hidden').focus();

}

}

Page 84: Securing TodoMVC Using the Web Cryptography API

Enter and Validate Password

On subsequent uses, password must be entered to unlock todos.

An invalid password will shake the password input field and outline in red.

Page 85: Securing TodoMVC Using the Web Cryptography API

CSS3 Shake Animation#todo-password.invalid {

margin-left: 50px;

padding: 3px 3px 3px 7px;

border: 3px solid;

width: 493px;

border-radius: 6px;

border-color: red;

outline-color: red;

animation: shake .5s linear;

}

@keyframes shake {

8%, 41% { transform: translateX(-10px); }

25%, 58% { transform: translateX(10px); }

75% { transform: translateX(-5px); }

92% { transform: translateX(5px); }

0%, 100% { transform: translateX(0); }

}

Page 86: Securing TodoMVC Using the Web Cryptography API

Demo

Page 87: Securing TodoMVC Using the Web Cryptography API

validatePassword: function (password, confirmPassword) {

var that = this;

if (confirmPassword && confirmPassword != password) {

return new Promise(function (resolve, reject) {

reject(new Error('passwords do not match'));

});

}

return cryptoStorage.authenticate(password).then(function () {

return util.store();

}).then(function (result) {

that.todos = result;

})

}

Page 88: Securing TodoMVC Using the Web Cryptography API

Convert store to return a Promise

store: function (data) {

if (data) {

return cryptoStorage.setItem(data);

} else {

return cryptoStorage.getItem();

}

}

Page 89: Securing TodoMVC Using the Web Cryptography API

Data Flow and Storage (API)

Page 90: Securing TodoMVC Using the Web Cryptography API

Random IV and Salt

if ( !this.initialized ) {

this.salt = new Uint8Array( 32 );

$.WebCryptoAPI.getRandomValues( this.salt );

this.hexSalt = $.Uint8Util.toHexString( this.salt );

this.iv = new Uint8Array( 16 );

$.WebCryptoAPI.getRandomValues( this.iv );

this.hexIV = $.Uint8Util.toHexString( this.iv );

this.initialized = true;

}

Page 91: Securing TodoMVC Using the Web Cryptography API

return $.WebCryptoAPI.subtle.importKey('raw', this.salt, hmacSha256,

true, ['sign', 'verify'])

.then(function (keyResult) {

});

Generate Key from Password

Page 92: Securing TodoMVC Using the Web Cryptography API

return $.WebCryptoAPI.subtle.importKey('raw', this.salt, hmacSha256,

true, ['sign', 'verify'])

.then(function (keyResult) {

return $.WebCryptoAPI.subtle.sign(hmacSha256, keyResult, buf)

.then(function (signResult) {

});

});

Generate Key from Password

Page 93: Securing TodoMVC Using the Web Cryptography API

return $.WebCryptoAPI.subtle.importKey('raw', this.salt, hmacSha256,

true, ['sign', 'verify'])

.then(function (keyResult) {

return $.WebCryptoAPI.subtle.sign(hmacSha256, keyResult, buf)

.then(function (signResult) {

var keyBuf = new Uint8Array(signResult);

// importKey for later AES encryption

return $.WebCryptoAPI.subtle.importKey('raw', keyBuf, {name: 'AES-CBC'},

true, ['encrypt', 'decrypt'])

.then(function (result) {

});

});

});

Generate Key from Password

Page 94: Securing TodoMVC Using the Web Cryptography API

return $.WebCryptoAPI.subtle.importKey('raw', this.salt, hmacSha256,

true, ['sign', 'verify'])

.then(function (keyResult) {

return $.WebCryptoAPI.subtle.sign(hmacSha256, keyResult, buf)

.then(function (signResult) {

var keyBuf = new Uint8Array(signResult);

// importKey for later AES encryption

return $.WebCryptoAPI.subtle.importKey('raw', keyBuf, {name: 'AES-CBC'},

true, ['encrypt', 'decrypt'])

.then(function (result) {

that.encryptionKey = result;

if (!that.hasTodos) {

return that.setItem([]);

}

});

});

});

Generate Key from Password

Page 95: Securing TodoMVC Using the Web Cryptography API

Encrypt and Storevar encoder = new TextEncoder();

var todosBuf = encoder.encode(JSON.stringify(value));

var aesCbc = {name: 'AES-CBC', iv: this.iv };

var data = {

salt: this.hexSalt,

iv: this.hexIV,

ciphertext: null

};

return $.WebCryptoAPI.subtle.encrypt(aesCbc, this.encryptionKey,

todosBuf)

.then(function (result) {

data.ciphertext = $.Uint8Util.toHexString(new Uint8Array(result));

localStorage.setItem(NAMESPACE, JSON.stringify(data));

});

Page 96: Securing TodoMVC Using the Web Cryptography API

Decryptvar todosBuf = $.Uint8Util.fromHexString(data.ciphertext);

var aesCbc = {name: 'AES-CBC', iv: this.iv };

$.WebCryptoAPI.subtle.decrypt(aesCbc, this.encryptionKey, todosBuf)

.then(function (result) {

var decoder = new TextDecoder();

var plaintext = decoder.decode(new Uint8Array(result));

try {

data.todos = JSON.parse(plaintext);

resolve(data.todos);

} catch (err) {

reject(err);

}

}, function (err) {

reject(err);

});

Page 97: Securing TodoMVC Using the Web Cryptography API

Encrypted in localStorage

sqlite> select * from ItemTable;

todos-jquery-webcryptoapi|{"salt":"455ad2b6be02de86226c8c10fe32ebfc439b197f6b0a791894dab6f6920e22ff","iv":"29b0b0092148e5fa849931c821627ea7","ciphertext":"b1770f7729edde3736eb4c26df6f4a56a236e01c525e157cf24ce76b35f8c622845a97f561c2c13942677db765e0638ef2ed90f191d5d57dcfc22fc7cd4c712716fc0e6e8748fb950430cb11a7e5c66ca4c55df4d88551d5b88666cd7fa4330c85f20e88e30da752adf24ad71913bfb9"}

Page 98: Securing TodoMVC Using the Web Cryptography API
Page 99: Securing TodoMVC Using the Web Cryptography API

Questions?(and hopefully answers)