From 4ad29e25f3ba048521b71b4faa48b13836de9019 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Sat, 14 Apr 2018 23:20:37 -0400 Subject: [PATCH] stub out crypto function service with pbkdf2 --- package-lock.json | 10 +++--- package.json | 1 + src/abstractions/cryptoFunction.service.ts | 3 ++ src/services/nodeCryptoFunction.service.ts | 17 +++++++++ src/services/webCryptoFunction.service.ts | 42 ++++++++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/abstractions/cryptoFunction.service.ts create mode 100644 src/services/nodeCryptoFunction.service.ts create mode 100644 src/services/webCryptoFunction.service.ts diff --git a/package-lock.json b/package-lock.json index 5f769ef6a9..4d7d5667fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -100,7 +100,7 @@ "integrity": "sha512-PlKJw6ujJXLJjbvB3T0UCbY3jibKM6/Ya5cc9j1q+mYDeK3aR4Dp+20ZwxSuvJr9mIoPxp7+IL4aMOEvsscRTA==", "dev": true, "requires": { - "@types/node": "8.5.7" + "@types/node": "8.0.19" } }, "@types/handlebars": { @@ -140,9 +140,9 @@ "dev": true }, "@types/node": { - "version": "8.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.7.tgz", - "integrity": "sha512-+1ZfzGIq8Y3EV7hPF7bs3i+Gi2mqYOiEGGRxGYPrn+hTYLMmzg+/5TkMkCHiRtLB38XSNvr/43aQ9+cUq4BbBg==", + "version": "8.0.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.19.tgz", + "integrity": "sha512-VRQB+Q0L3YZWs45uRdpN9oWr82meL/8TrJ6faoKT5tp0uub2l/aRMhtm5fo68h7kjYKH60f9/bay1nF7ZpTW5g==", "dev": true }, "@types/node-forge": { @@ -163,7 +163,7 @@ "integrity": "sha1-IpwVfGvB5n1rmQ5sXhjb0v9Yz/A=", "dev": true, "requires": { - "@types/node": "8.5.7" + "@types/node": "8.0.19" } }, "@types/webcrypto": { diff --git a/package.json b/package.json index b63e1baeb6..5d4f7e55dc 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@angular/router": "5.2.0", "@angular/upgrade": "5.2.0", "@types/lunr": "2.1.5", + "@types/node": "8.0.19", "@types/node-forge": "0.7.1", "@types/papaparse": "4.1.31", "@types/webcrypto": "0.0.28", diff --git a/src/abstractions/cryptoFunction.service.ts b/src/abstractions/cryptoFunction.service.ts new file mode 100644 index 0000000000..5daffbd4f2 --- /dev/null +++ b/src/abstractions/cryptoFunction.service.ts @@ -0,0 +1,3 @@ +export abstract class CryptoFunctionService { + pbkdf2: (password: Buffer, salt: Buffer, iterations: number, length: number) => Promise +} diff --git a/src/services/nodeCryptoFunction.service.ts b/src/services/nodeCryptoFunction.service.ts new file mode 100644 index 0000000000..750b18a78d --- /dev/null +++ b/src/services/nodeCryptoFunction.service.ts @@ -0,0 +1,17 @@ +import * as crypto from 'crypto'; + +import { CryptoFunctionService } from '../abstractions/cryptoFunction.service'; + +export class NodeCryptoFunctionService implements CryptoFunctionService { + async pbkdf2(password: Buffer, salt: Buffer, iterations: number, length: number): Promise { + return new Promise((resolve, reject) => { + crypto.pbkdf2(password, salt, iterations, length, 'sha256', (error, key) => { + if (error != null) { + reject(error); + } else { + resolve(key.buffer); + } + }); + }); + } +} diff --git a/src/services/webCryptoFunction.service.ts b/src/services/webCryptoFunction.service.ts new file mode 100644 index 0000000000..ea563b32c8 --- /dev/null +++ b/src/services/webCryptoFunction.service.ts @@ -0,0 +1,42 @@ +import * as forge from 'node-forge'; + +import { CryptoFunctionService } from '../abstractions/cryptoFunction.service'; +import { PlatformUtilsService } from '../abstractions/platformUtils.service'; + +export class WebCryptoFunctionService implements CryptoFunctionService { + private crypto: Crypto; + private subtle: SubtleCrypto; + + constructor(private win: Window, private platformUtilsService: PlatformUtilsService) { + this.crypto = win.crypto; + this.subtle = win.crypto.subtle; + } + + async pbkdf2(password: Buffer, salt: Buffer, iterations: number, length: number): Promise { + const importedKey = await this.subtle.importKey('raw', password, { name: 'PBKDF2' }, + false, ['deriveKey', 'deriveBits']); + + const alg: Pbkdf2Params = { + name: 'PBKDF2', + salt: salt, + iterations: iterations, + hash: { name: 'SHA-256' }, + }; + + const keyType: AesDerivedKeyParams = { + name: 'AES-CBC', + length: length, + }; + + const derivedKey = await this.subtle.deriveKey(alg, importedKey, keyType, true, ['encrypt', 'decrypt']); + return await this.subtle.exportKey('raw', derivedKey); + } + + async sha1(value: Buffer): Promise { + if (this.platformUtilsService.isEdge()) { + return new Uint8Array([1]).buffer; // TODO: sha1 with forge + } else { + return await this.subtle.digest({ name: 'SHA-1' }, value); + } + } +}