crypto function implementations
This commit is contained in:
parent
4ad29e25f3
commit
d6474aee0e
|
@ -1,3 +1,4 @@
|
||||||
export abstract class CryptoFunctionService {
|
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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,24 @@ import * as crypto from 'crypto';
|
||||||
import { CryptoFunctionService } from '../abstractions/cryptoFunction.service';
|
import { CryptoFunctionService } from '../abstractions/cryptoFunction.service';
|
||||||
|
|
||||||
export class NodeCryptoFunctionService implements CryptoFunctionService {
|
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) => {
|
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) {
|
if (error != null) {
|
||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,6 +3,8 @@ import * as forge from 'node-forge';
|
||||||
import { CryptoFunctionService } from '../abstractions/cryptoFunction.service';
|
import { CryptoFunctionService } from '../abstractions/cryptoFunction.service';
|
||||||
import { PlatformUtilsService } from '../abstractions/platformUtils.service';
|
import { PlatformUtilsService } from '../abstractions/platformUtils.service';
|
||||||
|
|
||||||
|
import { UtilsService } from '../services/utils.service';
|
||||||
|
|
||||||
export class WebCryptoFunctionService implements CryptoFunctionService {
|
export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||||
private crypto: Crypto;
|
private crypto: Crypto;
|
||||||
private subtle: SubtleCrypto;
|
private subtle: SubtleCrypto;
|
||||||
|
@ -12,15 +14,35 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||||
this.subtle = win.crypto.subtle;
|
this.subtle = win.crypto.subtle;
|
||||||
}
|
}
|
||||||
|
|
||||||
async pbkdf2(password: Buffer, salt: Buffer, iterations: number, length: number): Promise<ArrayBuffer> {
|
async pbkdf2(password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512',
|
||||||
const importedKey = await this.subtle.importKey('raw', password, { name: 'PBKDF2' },
|
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']);
|
false, ['deriveKey', 'deriveBits']);
|
||||||
|
|
||||||
const alg: Pbkdf2Params = {
|
const alg: Pbkdf2Params = {
|
||||||
name: 'PBKDF2',
|
name: 'PBKDF2',
|
||||||
salt: salt,
|
salt: saltBuf,
|
||||||
iterations: iterations,
|
iterations: iterations,
|
||||||
hash: { name: 'SHA-256' },
|
hash: { name: algorithm === 'sha256' ? 'SHA-256' : 'SHA-512' },
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyType: AesDerivedKeyParams = {
|
const keyType: AesDerivedKeyParams = {
|
||||||
|
@ -32,11 +54,21 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||||
return await this.subtle.exportKey('raw', derivedKey);
|
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()) {
|
if (this.platformUtilsService.isEdge()) {
|
||||||
return new Uint8Array([1]).buffer; // TODO: sha1 with forge
|
// TODO
|
||||||
} else {
|
return new Uint8Array([]).buffer;
|
||||||
return await this.subtle.digest({ name: 'SHA-1' }, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue