End End-to-end File Encr Encryp yption i in n the the Web Br - - PowerPoint PPT Presentation

end end to end file encr encryp yption i in n the the web
SMART_READER_LITE
LIVE PREVIEW

End End-to-end File Encr Encryp yption i in n the the Web Br - - PowerPoint PPT Presentation

End End-to-end File Encr Encryp yption i in n the the Web Br eb Browser er A Ca Case e Study dy Thomas Konrad, SBA Research Vue.js Meetup Vienna, Feb 11, 2020 SBA Research gGmbH, 2020 Classification: Public 1 ~ $ whoami Thomas


slide-1
SLIDE 1

Classification: Public 1

End End-to-end File Encr Encryp yption i in n the the Web Br eb Browser er – A Ca Case e Study dy

Thomas Konrad, SBA Research Vue.js Meetup Vienna, Feb 11, 2020

SBA Research gGmbH, 2020

slide-2
SLIDE 2

Classification: Public 2 SBA Research gGmbH, 2020

~$ whoami Thomas Konrad ~$ id uid=123 gid=1(Vienna, Austria) gid=2(SBA Research) gid=3(Software Security) gid=4(Penetration Testing) gid=5(Secure Development Lifecycle) gid=6(Security Training) gid=7(sec4dev Conference & Bootcamp)

slide-3
SLIDE 3

Classification: Public 3

Wha What t we’d e’d like t e to

  • do

SBA Research gGmbH, 2020

slide-4
SLIDE 4

Classification: Public 4

Wh Why y al all th the e Fuzz? zz?

  • Beecozz Sucurity!
  • No, seriously
  • To lower the attack

surface significantly!

  • File read access on the

server gets worthless to attackers

  • Maybe better

deployment options

SBA Research gGmbH, 2020

slide-5
SLIDE 5

Classification: Public 5

I a I admi mit: I d : I didn’t i n’t inven nvent t th this. s.

SBA Research gGmbH, 2020

  • Firefox Send
  • End-to-end encrypted file sharing
  • Basic concepts in this talk are

taken from there

  • https://send.firefox.com
  • https://github.com/mozilla/send
  • Good stuff!
slide-6
SLIDE 6

Classification: Public 6

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-7
SLIDE 7

Classification: Public 7

Ensure nsure Conf nfiden enti tial ality ty, Int Integri egrity ty, an and Authenti uthentici city ty

First things first: Randomness. 1110 1101 0001 1101 0000 0000 0000 0000 “There is no such thing as a random number – there are

  • nly methods to produce random numbers.”

– John von Neumann (1961)

SBA Research gGmbH, 2020

slide-8
SLIDE 8

Classification: Public 8

Gener Generate e Secu ecure re Rand ndom B

  • m Byt

ytes es in th the e Browser ser

SBA Research gGmbH, 2020

public static generateRandomBytes( length: number ): Uint8Array { return crypto.getRandomValues( new Uint8Array(length) ); }

GitHub Gist - Random Number Generator in TypeScript: https://gist.github.com/thomaskonrad/cfe4c9f6fd26f4382df1f8de3a2b97e8

slide-9
SLIDE 9

Classification: Public 9

Ensure nsure Conf nfiden enti tial ality ty, Int Integri egrity ty, an and Authenti uthentici city ty

Let’s take as an example AES in CBC mode. What do you think we can guarantee with it? Confidentiality Integrity Authenticity

SBA Research gGmbH, 2020

slide-10
SLIDE 10

Classification: Public 10

CBC (an (and other thers) s) Do N

  • Not Gu
  • t Guar

aran antee ee Int Integri egrity ty

  • The ciphertext can be manipulated, and

decryption will not fail.

  • Solution
  • Authenticated Encryption with Associated Data

(AEAD)

  • Examples: AES-GCM, ChaCha20-Poly1305

SBA Research gGmbH, 2020

slide-11
SLIDE 11

Classification: Public 11

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-12
SLIDE 12

Classification: Public 12

Symme ymmetric tric AEAD AEAD Enc Encryp yption tion in in the the Brow

  • wse

ser r 1/2

SBA Research gGmbH, 2020

export default class AEAD { public static readonly KEY_LENGTH_IN_BYTES = 16; public static readonly IV_LENGTH_IN_BYTES = 16; public static readonly TAG_LENGTH_IN_BYTES = 16; private static readonly ALGORITHM = 'AES-GCM'; private readonly secretKey: CryptoKey; private readonly tagLengthInBytes: number; public constructor(secretKey: CryptoKey, tagLengthInBytes = AEAD.TAG_LENGTH_IN_BYTES) { this.secretKey = secretKey; this.tagLengthInBytes = tagLengthInBytes; } public static async getCryptoKeyFromRawKey(rawKey: Uint8Array): Promise<CryptoKey> { return await crypto.subtle.importKey( 'raw', rawKey, { name: this.ALGORITHM, }, true, ['encrypt', 'decrypt'], ); }

GitHub Gist - Authenticated Secret Key Cryptography (AEAD) in TypeScript: https://gist.github.com/thomaskonrad/c8ed4d73bb200ecc9ecdf5b85e2eb7f0

slide-13
SLIDE 13

Classification: Public 13

Symme ymmetric tric AEAD AEAD Enc Encryp yption tion in in the the Brow

  • wse

ser r 2/2

SBA Research gGmbH, 2020

public async encrypt(iv: Uint8Array, data: Uint8Array): Promise<ArrayBuffer> { return await crypto.subtle.encrypt({ name: AuthenticatedSecretKeyCryptography.ALGORITHM, iv, tagLength: this.tagLengthInBytes * 8, }, this.secretKey, data, ); } public async decrypt(iv: Uint8Array, data: Uint8Array): Promise<ArrayBuffer> { return await crypto.subtle.decrypt({ name: AuthenticatedSecretKeyCryptography.ALGORITHM, iv, tagLength: this.tagLengthInBytes * 8, }, this.secretKey, data, ); } }

GitHub Gist - Authenticated Secret Key Cryptography (AEAD) in TypeScript: https://gist.github.com/thomaskonrad/c8ed4d73bb200ecc9ecdf5b85e2eb7f0

slide-14
SLIDE 14

Classification: Public 14

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-15
SLIDE 15

Classification: Public 15

Upload ad: C : Chu hunk a nk and nd Encr Encryp ypt

SBA Research gGmbH, 2020

slide-16
SLIDE 16

Classification: Public 16

Upload load: : Splitting litting a a Fil File using using the the Fil FileRead ader r API API

SBA Research gGmbH, 2020

<template> <input type="file" @change="files = $event.target.files"/> </template> // ... const readChunk = () => { const r = new FileReader(); const blob = file.slice(offset, chunkSize + offset); r.onload = readEventHandler; r.readAsArrayBuffer(blob); };

GitHub Gist - Split files into chunks of a given size using the FileReader API: https://gist.github.com/thomaskonrad/8ced18322ebfcba47d7e8765176eeefb

slide-17
SLIDE 17

Classification: Public 17

Upload load: : Splitting litting a a Fil File using using the the Fil FileRead ader r API API

SBA Research gGmbH, 2020

const readEventHandler = async (evt: any) => { if (evt.target.error == null) { const sequenceNumber = (offset / chunkSize);

  • ffset += evt.target.result.byteLength;

let data = new Uint8Array(evt.target.result); data = await encrypt(data, sequenceNumber); await upload(data, sequenceNumber); } // Error handling, termination, read next chunk. };

GitHub Gist - Split files into chunks of a given size using the FileReader API: https://gist.github.com/thomaskonrad/8ced18322ebfcba47d7e8765176eeefb

slide-18
SLIDE 18

Classification: Public 18

Upload load: : Cre Creating ating the the Enc Encryp yption tion Transf ansforme

  • rmer

SBA Research gGmbH, 2020

const encrypt = async (chunk: Uint8Array, chunkIndex: number) => { return await this.keyChain.encrypt( chunk, file.nonce, // A random, 12-byte nonce! 'fileContents’, chunkIndex // This will be part of the nonce. ); };

slide-19
SLIDE 19

Classification: Public 19

Fi FileR eRead eader er API: I: Brow

  • wser

ser Sup uppor

  • rt

SBA Research gGmbH, 2020

slide-20
SLIDE 20

Classification: Public 20

Dow

  • wnl

nloa

  • ad: D

: Dow

  • wnl

nload ad a as s Blob?

SBA Research gGmbH, 2020

async blobDownload(file: File) { const response = await this.$http.get( `/api/v1/files/${file.id}`, { responseType: 'blob' }, ); const cleartext = await this.keyChain.getDecryptedResponseData( response.data, file.nonce, file.totalClearTextSizeInBytes, ); await saveFile(cleartext, file.name, file.mimeType); }

slide-21
SLIDE 21

Classification: Public 21

Dow

  • wnl

nloa

  • ad:

: Crea reati ting ng a a ”S ”Save ave as” D s” Dialog

SBA Research gGmbH, 2020

export default async function saveFile(plaintext: ArrayBuffer, fileName: string, fileType: string) { return new Promise((resolve, reject) => { const dataView = new DataView(plaintext); const blob = new Blob([dataView], { type: fileType }); const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = fileName; document.body.appendChild(a); a.click(); URL.revokeObjectURL(downloadUrl); setTimeout(resolve, 100); }); }

GitHub Gist: Downloading an Array Buffer via a "Save as" Dialog in the Browser: https://gist.github.com/thomaskonrad/37772256a86d9f5b0472b3c2440cffee

slide-22
SLIDE 22

Classification: Public 22

Dow

  • wnl

nloa

  • ad:

: Dow

  • wnsi

nsides es of th f this s Approa

  • ach
  • A 10 GB file will use 20 GB+ of memory
  • Using this approach, we cannot stream the data
  • Enter Service Workers!

SBA Research gGmbH, 2020

slide-23
SLIDE 23

Classification: Public 23

Ser ervi vice ce Worker ers: s: A Quick P k Pri rimer mer

  • A piece of JavaScript code that runs in the

background of your website

  • It acts as a proxy server between your site and

the server

  • It runs in a worker context and has no DOM

access

SBA Research gGmbH, 2020

slide-24
SLIDE 24

Classification: Public 24

Ser ervi vice ce Worker ers: s: A Quick P k Pri rimer mer

  • Service Worker use cases
  • Intercepting and modifying requests
  • Caching resources
  • Convert images
  • Can make your app work even if no network is

available (Progressive Web Apps, PWA)

SBA Research gGmbH, 2020

slide-25
SLIDE 25

Classification: Public 25

Ser ervi vice ce Worker ers: s: A Quick P k Pri rimer mer

SBA Research gGmbH, 2020

slide-26
SLIDE 26

Classification: Public 26

Regi egisteri ering g a a Ser ervi vice ce Wor

  • rker

er

SBA Research gGmbH, 2020

if ('serviceWorker' in navigator) { // Register a service worker hosted at the root of the // site using a more restrictive scope. navigator.serviceWorker.register('/sw.js’, { scope: './’ }).then((registration) => { console.log(‘Registration succeeded:', registration); }, /*catch*/ (error) => { console.log('Service worker registration failed:', error); }); } else { console.log('Service workers are not supported.'); }

Source: https://developer.mozilla.org/en- US/docs/Web/API/ServiceWorkerContainer/register

slide-27
SLIDE 27

Classification: Public 27

Acti ctivat ate e th the e Ser ervi vice ce Wor

  • rker

er Immed Immediat atel ely

SBA Research gGmbH, 2020

// In sw.js self.addEventListener('install', (event) => { // Activate the Service Worker as soon as it’s // finished installing. event.waitUntil(self.skipWaiting()); }); self.addEventListener('activate', (event) => { // Make the Service Worker become immediately // available to all pages. event.waitUntil(self.clients.claim()); });

slide-28
SLIDE 28

Classification: Public 28

Dow

  • wnl

nloa

  • ad:

: Decr ecryp ypt t the the Fi File e in th the e SW

SBA Research gGmbH, 2020

slide-29
SLIDE 29

Classification: Public 29

Ser ervi vice ce Wor

  • rker

ers: s: Brow

  • wser

ser Sup uppor

  • rt

SBA Research gGmbH, 2020

slide-30
SLIDE 30

Classification: Public 30

Dow

  • wnl

nloa

  • ad: The

: The ReadableStream API API

  • Readable stream of byte data
  • The Fetch API returns a ReadableStream object

through the body property of the Response

  • bject

SBA Research gGmbH, 2020

const response = await fetch(file.url, requestOptions); const readableStream: ReadableStream<Uint8Array> = response.body;

slide-31
SLIDE 31

Classification: Public 31

Dow

  • wnl

nloa

  • ad: The

: The Decr ecryp ypti tion

  • n Stream

tream

SBA Research gGmbH, 2020

public async getDecryptionStream( responseBody: ReadableStream<Uint8Array>,

  • bjectNonce: string,

): Promise<ReadableStream> { await this.initializeAEADIfNotInitialized(); const slicesStream = transformStream( responseBody, new StreamSlicer(this.chunkSizeInBytes + this.tagLengthInBytes), ); return transformStream( slicesStream, new DecryptStreamController(this, objectNonce, 'fileContents'), ); }

GitHub Gist - Splits a ReadableStream into chunks of a given size.: https://gist.github.com/thomaskonrad/b8f30e3f18ea2f538bdf422203bdc473

slide-32
SLIDE 32

Classification: Public 32

Dow

  • wnl

nloa

  • ad: The

: The

DecryptStreamController

SBA Research gGmbH, 2020

export default class DecryptStreamController { public async transform(chunk: any, controller: any){ const clearText = await this.keyChain.decrypt( chunk, this.objectNonce, this.attributeName, this.chunkIndex ); controller.enqueue(Buffer.from(clearText)); this.chunkIndex ++; } }

slide-33
SLIDE 33

Classification: Public 33

ReadableStream API API: Br Browser Suppor Support

SBA Research gGmbH, 2020

slide-34
SLIDE 34

Classification: Public 34

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-35
SLIDE 35

Classification: Public 35

Suppor

  • rti

ting ng Ol Old B Brow

  • wser

sers

  • Upload
  • The FileReader API is well supported
  • So no problem!
  • Download
  • Requires Service Workers and native streams
  • Just Chromium-based and Gecko-based browsers
  • But we can use the blob download!

SBA Research gGmbH, 2020

slide-36
SLIDE 36

Classification: Public 36

Rememb emember? er? Creati reating g a ”S ”Save ave as” s” Dialog

  • g

SBA Research gGmbH, 2020

export default async function saveFile(plaintext: ArrayBuffer, fileName: string, fileType: string) { return new Promise((resolve, reject) => { const dataView = new DataView(plaintext); const blob = new Blob([dataView], { type: fileType }); const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = fileName; document.body.appendChild(a); a.click(); URL.revokeObjectURL(downloadUrl); setTimeout(resolve, 100); }); }

GitHub Gist: Downloading an Array Buffer via a "Save as" Dialog in the Browser: https://gist.github.com/thomaskonrad/37772256a86d9f5b0472b3c2440cffee

slide-37
SLIDE 37

Classification: Public 37

Suppor

  • rti

ting ng Ol Old B Brow

  • wser

sers

  • Blob download
  • We can use it for
  • lder browsers
  • But we must limit

the file size,

  • E.g. max. 256 MB

SBA Research gGmbH, 2020

slide-38
SLIDE 38

Classification: Public 38

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-39
SLIDE 39

Classification: Public 39

Shari aring ng the the Mas Master er Key ey

  • Requirements
  • Share the file via link
  • The key must not be

transferred to the server

SBA Research gGmbH, 2020

slide-40
SLIDE 40

Classification: Public 40

The The URL

https://example.org/path/to/resource?a=b&c=d#x

SBA Research gGmbH, 2020

Scheme Domain Resource path Query Fragment

slide-41
SLIDE 41

Classification: Public 41

The The URL L Fragmen gment t Stays s in th the e Browser ser

SBA Research gGmbH, 2020

slide-42
SLIDE 42

Classification: Public 42

A Fi File e URL L in n Fi Firef refox

  • x Sen

end

https://send.firefox.com/download/9b91257c383393cb/#MlbZpG67ubEXXGTmM-p_6w

SBA Research gGmbH, 2020

Access token Key

slide-43
SLIDE 43

Classification: Public 43

Req equiremen rements ts

SBA Research gGmbH, 2020

Ensure confidentiality, integrity, and authenticity Encrypt the file in the browser Support big files (> 10 GB) Support old browsers as well as possible Securely distribute keys

slide-44
SLIDE 44

Classification: Public 44 SBA Research gGmbH, 2020

Demo mo Time me!

Photo by Yancy Min on Unsplash

slide-45
SLIDE 45

Classification: Public 45

Wrapping apping up up

What we have learned today

SBA Research gGmbH, 2020

slide-46
SLIDE 46

Classification: Public 46

Wrap apping ng up up

  • Ensure confidentiality, integrity, and

authenticity

  • Non-AEAD ciphers don’t guarantee integrity and

authenticity

  • Use AEAD ciphers like AES-GCM
  • Use a unique initialization vector (IV) every time

you encrypt something

SBA Research gGmbH, 2020

slide-47
SLIDE 47

Classification: Public 47

Wrap apping ng up up

  • Cryptography in the browser
  • Modern browsers ship with the Web Crypto API
  • Use crypto.getRandomValues to generate

random bytes

  • Use crypto.subtle.importKey,

crypto.subtle.encrypt and crypto.subtle.decrypt to encrypt data in the browser

SBA Research gGmbH, 2020

slide-48
SLIDE 48

Classification: Public 48

Wrap apping ng up up

  • Chunked upload
  • Use the FileReader API to chunk files that you get from

an <input type="file"/> input

  • Chunked download
  • Use a Service Worker to intercept requests
  • Use the ReadableStream API to chunk and decrypt
  • Support limited size downloads for old browsers via

blob download

SBA Research gGmbH, 2020

slide-49
SLIDE 49

Classification: Public 49

sec4 ec4dev v Boo

  • otcamp

tcamp: : A Builder’s er’s Gu Guide e to Singl gle e Page ge Applicati cation n Secu ecuri rity ty

SBA Research gGmbH, 2020

  • Philippe De Ryck
  • 24 – 26 Feb 2020
  • TU Wien, Audimax
  • Learn to build secure SPAs
  • Cross-site Scripting (XSS)
  • Content Security Policy (CSP)
  • Cross-origin Resource Sharing (CORS)
  • Protecting against malicious third-party

content

  • JWT best practices
  • Oauth 2.0 and OpenID Connect
  • https://sec4dev.io
slide-50
SLIDE 50

Classification: Public 50 SBA Research gGmbH, 2020

Thomas Konrad SBA Research tkonrad@sba-research.org @_thomaskonrad

Photo by Morvanic Lee on Unsplash