The Web Crypto API
Katy Moe
About me
JavaScript Engineer at Kahoot!
mathematician
digital rights enthusiast
Introduction
1. intro to crypto
2. why we need web crypto
3. how to use the API
4. the spec
The next twenty minutes
Intro to crypto
Crypto is about keeping secrets
THIS IS A SECRET MESSAGE TO BE XORED WITH A SECRET KEY TO PRODUCE A CIPHERTEXT. THIS IS CALLED ENCRYPTION.
plaintext
HSD0472B1VX8V5BLR02010DHCV8B6W25N6KGBJV9SYS9C6 5BOG98383BY398Y98FR9GBBV2964783NHJFIFNJB90N7480
9GFGJFHGD76FVB2C1SD1SA2P408G00ZXBVB302479DHFJHAA83T1VSNXYBV8B9CBVA7F5395GKVBQ9X8GK2N1V49V09
+
=
key
ciphertext
Symmetric cryptography
H487SBFK593OSFH0N8BLSK4278SBTOB9P
Alice
Alice
Alice's key
Alice's key
my secret
my secret
Public key cryptography
H487SBFK593OSFH0N8BLSK4278SBTOB9P
Alice
Bob
Bob's public key
Bob's private key
Hello, Bob!
Hello, Bob!
Randomness
Cryptographically
Secure
Pseudo-
Random
Number
Generator
Math.random()
Random.org
?
?
?
?
?
?
The Web Crypto API: crypto in the browser
But we already have TLS
browser
server
browser
TLS
TLS
plaintext
plaintext
plaintext
link layer
internet/IP layer
transport layer
application layer
TLS
Web Crypto API
JS || GTFO
// 1. create key buffer
const keyArrayBuffer = new Uint8Array([0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff]);
// 2. encode plaintext
const encoder = new TextEncoder('utf-8');
const plaintext = 'Alice has a secret';
const encodedPlaintext = encoder.encode(plaintext);
// 3. import raw key
window.crypto.subtle.importKey(
'raw', keyArrayBuffer, {
name: 'AES-GCM'
}, false, ['encrypt', 'decrypt']
).then(function(key) {
// 4. generate random IV
const iv = window.crypto.getRandomValues(new Uint8Array(12));
// 5. encrypt
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv
}, key, encodedPlaintext);
}).then(function(ciphertext) {
console.log(new Uint8Array(ciphertext));
});
5. encrypt
1. create key buffer
2. encode plaintext
3. import raw key
4. generate random IV
Symmetric encryption
window.crypto.getRandomValues
window.crypto.subtle
1. create key buffer
const keyArrayBuffer = new Uint8Array([0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff]);
2. encode plaintext
const encoder = new TextEncoder('utf-8');
const plaintext = 'Alice has a secret';
const encodedPlaintext = encoder.encode(plaintext);
3. import raw key
// def: keyArrayBuffer
window.crypto.subtle.importKey(
'raw',
keyArrayBuffer,
{ name: 'AES-GCM' },
false,
['encrypt', 'decrypt']
);
4. generate random IV
const iv = window.crypto.getRandomValues(new Uint8Array(12));
5. encrypt
// def: encodedPlaintext, iv, key
window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv
}, key, encodedPlaintext);
// 1. create key buffer
const keyArrayBuffer = new Uint8Array([0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff]);
// 2. encode plaintext
const encoder = new TextEncoder('utf-8');
const plaintext = 'Alice has a secret';
const encodedPlaintext = encoder.encode(plaintext);
// 3. import raw key
window.crypto.subtle.importKey(
'raw', keyArrayBuffer, {
name: 'AES-GCM'
}, false, ['encrypt', 'decrypt']
).then(function(key) {
// 4. generate random IV
const iv = window.crypto.getRandomValues(new Uint8Array(12));
// 5. encrypt
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv
}, key, encodedPlaintext);
}).then(function(ciphertext) {
console.log(new Uint8Array(ciphertext));
});
The spec
Working Draft
Candidate Recommendation
Proposed Recommendation
W3C Recommendation
Web Crypto API
Browser support
Opinions on the API
1. Why so many params?
2. How do we discover
algorithms?
3. Why not recommend algorithms?
The Web Crypto API: crypto in the browser
Thank you
Kahoot! is hiring!
Resources
Opinions
- What's wrong with in-browser cryptography? - Tony Arcieri
- No I didn't use the Web Crypto API - Calvin Metcalf
- JavaScript cryptography considered harmful - Thomas Ptacek
- The anatomy of a bad idea - Matthew Green
The Web Crypto API
By Katharine Moe
The Web Crypto API
A talk on the Web Crypto API to be given at Front-End London on Thursday 29th October 2015.
- 3,654