crypto function implementations

This commit is contained in:
Kyle Spearrin 2018-04-16 12:07:51 -04:00
parent 4ad29e25f3
commit d6474aee0e
3 changed files with 59 additions and 11 deletions

View File

@ -1,3 +1,4 @@
export abstract class CryptoFunctionService {
pbkdf2: (password: Buffer, salt: Buffer, iterations: number, length: number) => Promise<ArrayBuffer>
pbkdf2: (password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512',
iterations: number, length: number) => Promise<ArrayBuffer>;
}

View File

@ -3,9 +3,24 @@ 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<ArrayBuffer> {
async pbkdf2(password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512',
iterations: number, length: number): Promise<ArrayBuffer> {
let nodePassword: string | Buffer;
if (typeof (password) === 'string') {
nodePassword = password;
} else {
nodePassword = Buffer.from(new Uint8Array(password) as any);
}
let nodeSalt: string | Buffer;
if (typeof (salt) === 'string') {
nodeSalt = salt;
} else {
nodeSalt = Buffer.from(new Uint8Array(salt) as any);
}
return new Promise<ArrayBuffer>((resolve, reject) => {
crypto.pbkdf2(password, salt, iterations, length, 'sha256', (error, key) => {
crypto.pbkdf2(nodePassword, nodeSalt, iterations, length, algorithm, (error, key) => {
if (error != null) {
reject(error);
} else {

View File

@ -3,6 +3,8 @@ import * as forge from 'node-forge';
import { CryptoFunctionService } from '../abstractions/cryptoFunction.service';
import { PlatformUtilsService } from '../abstractions/platformUtils.service';
import { UtilsService } from '../services/utils.service';
export class WebCryptoFunctionService implements CryptoFunctionService {
private crypto: Crypto;
private subtle: SubtleCrypto;
@ -12,15 +14,35 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
this.subtle = win.crypto.subtle;
}
async pbkdf2(password: Buffer, salt: Buffer, iterations: number, length: number): Promise<ArrayBuffer> {
const importedKey = await this.subtle.importKey('raw', password, { name: 'PBKDF2' },
async pbkdf2(password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512',
iterations: number, length: number): Promise<ArrayBuffer> {
if (this.platformUtilsService.isEdge()) {
// TODO
return new Uint8Array([]).buffer;
}
let passwordBuf: ArrayBuffer;
if (typeof (password) === 'string') {
passwordBuf = UtilsService.fromUtf8ToArray(password).buffer;
} else {
passwordBuf = password;
}
let saltBuf: ArrayBuffer;
if (typeof (salt) === 'string') {
saltBuf = UtilsService.fromUtf8ToArray(salt).buffer;
} else {
saltBuf = salt;
}
const importedKey = await this.subtle.importKey('raw', passwordBuf, { name: 'PBKDF2' },
false, ['deriveKey', 'deriveBits']);
const alg: Pbkdf2Params = {
name: 'PBKDF2',
salt: salt,
salt: saltBuf,
iterations: iterations,
hash: { name: 'SHA-256' },
hash: { name: algorithm === 'sha256' ? 'SHA-256' : 'SHA-512' },
};
const keyType: AesDerivedKeyParams = {
@ -32,11 +54,21 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
return await this.subtle.exportKey('raw', derivedKey);
}
async sha1(value: Buffer): Promise<ArrayBuffer> {
async hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256'): Promise<ArrayBuffer> {
if (this.platformUtilsService.isEdge()) {
return new Uint8Array([1]).buffer; // TODO: sha1 with forge
} else {
return await this.subtle.digest({ name: 'SHA-1' }, value);
// TODO
return new Uint8Array([]).buffer;
}
let valueBuf: ArrayBuffer;
if (typeof (value) === 'string') {
valueBuf = UtilsService.fromUtf8ToArray(value).buffer;
} else {
valueBuf = value;
}
return await this.subtle.digest({
name: algorithm === 'sha256' ? 'SHA-256' : 'SHA-1'
}, valueBuf);
}
}