From 2045e7047a66599b2c8a92b88cd0d1b8bfc5186f Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 30 Jul 2018 23:29:30 -0400 Subject: [PATCH] add support for md5 hash crypto function --- spec/node/services/nodeCryptoFunction.service.spec.ts | 8 +++++++- spec/web/services/webCryptoFunction.service.spec.ts | 7 ++++++- src/abstractions/cryptoFunction.service.ts | 2 +- src/services/nodeCryptoFunction.service.ts | 2 +- src/services/webCryptoFunction.service.ts | 11 +++++++---- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/spec/node/services/nodeCryptoFunction.service.spec.ts b/spec/node/services/nodeCryptoFunction.service.spec.ts index 5f79750d5f..8b58312da6 100644 --- a/spec/node/services/nodeCryptoFunction.service.spec.ts +++ b/spec/node/services/nodeCryptoFunction.service.spec.ts @@ -65,9 +65,14 @@ describe('NodeCrypto Function Service', () => { const unicode512Hash = '2b16a5561af8ad6fe414cc103fc8036492e1fc6d9aabe1b655497054f760fe0e34c5d100ac773d' + '9f3030438284f22dbfa20cb2e9b019f2c98dfe38ce1ef41bae'; + const regularMd5 = '5eceffa53a5fd58c44134211e2c5f522'; + const utf8Md5 = '3abc9433c09551b939c80aa0aa3174e1'; + const unicodeMd5 = '85ae134072c8d81257933f7045ba17ca'; + testHash('sha1', regular1Hash, utf81Hash, unicode1Hash); testHash('sha256', regular256Hash, utf8256Hash, unicode256Hash); testHash('sha512', regular512Hash, utf8512Hash, unicode512Hash); + testHash('md5', regularMd5, utf8Md5, unicodeMd5); }); describe('hmac', () => { @@ -229,7 +234,8 @@ function testPbkdf2(algorithm: 'sha256' | 'sha512', regularKey: string, utf8Key: }); } -function testHash(algorithm: 'sha1' | 'sha256' | 'sha512', regularHash: string, utf8Hash: string, unicodeHash: string) { +function testHash(algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5', regularHash: string, + utf8Hash: string, unicodeHash: string) { const regularValue = 'HashMe!!'; const utf8Value = 'HǻshMe!!'; const unicodeValue = '😀HashMe!!!🙏'; diff --git a/spec/web/services/webCryptoFunction.service.spec.ts b/spec/web/services/webCryptoFunction.service.spec.ts index 7be59e73db..f3ad003bf8 100644 --- a/spec/web/services/webCryptoFunction.service.spec.ts +++ b/spec/web/services/webCryptoFunction.service.spec.ts @@ -71,9 +71,14 @@ describe('WebCrypto Function Service', () => { const unicode512Hash = '2b16a5561af8ad6fe414cc103fc8036492e1fc6d9aabe1b655497054f760fe0e34c5d100ac773d' + '9f3030438284f22dbfa20cb2e9b019f2c98dfe38ce1ef41bae'; + const regularMd5 = '5eceffa53a5fd58c44134211e2c5f522'; + const utf8Md5 = '3abc9433c09551b939c80aa0aa3174e1'; + const unicodeMd5 = '85ae134072c8d81257933f7045ba17ca'; + testHash('sha1', regular1Hash, utf81Hash, unicode1Hash); testHash('sha256', regular256Hash, utf8256Hash, unicode256Hash); testHash('sha512', regular512Hash, utf8512Hash, unicode512Hash); + testHash('md5', regularMd5, utf8Md5, unicodeMd5); }); describe('hmac', () => { @@ -315,7 +320,7 @@ function testPbkdf2(algorithm: 'sha256' | 'sha512', regularKey: string, }); } -function testHash(algorithm: 'sha1' | 'sha256' | 'sha512', regularHash: string, +function testHash(algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5', regularHash: string, utf8Hash: string, unicodeHash: string) { const regularValue = 'HashMe!!'; const utf8Value = 'HǻshMe!!'; diff --git a/src/abstractions/cryptoFunction.service.ts b/src/abstractions/cryptoFunction.service.ts index 72b64fac57..45b1014a29 100644 --- a/src/abstractions/cryptoFunction.service.ts +++ b/src/abstractions/cryptoFunction.service.ts @@ -4,7 +4,7 @@ import { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey'; export abstract class CryptoFunctionService { pbkdf2: (password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512', iterations: number) => Promise; - hash: (value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512') => Promise; + hash: (value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5') => Promise; hmac: (value: ArrayBuffer, key: ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512') => Promise; compare: (a: ArrayBuffer, b: ArrayBuffer) => Promise; hmacFast: (value: ArrayBuffer | string, key: ArrayBuffer | string, algorithm: 'sha1' | 'sha256' | 'sha512') => diff --git a/src/services/nodeCryptoFunction.service.ts b/src/services/nodeCryptoFunction.service.ts index eedacf5374..d88be72d99 100644 --- a/src/services/nodeCryptoFunction.service.ts +++ b/src/services/nodeCryptoFunction.service.ts @@ -26,7 +26,7 @@ export class NodeCryptoFunctionService implements CryptoFunctionService { }); } - hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512'): Promise { + hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5'): Promise { const nodeValue = this.toNodeValue(value); const hash = crypto.createHash(algorithm); hash.update(nodeValue); diff --git a/src/services/webCryptoFunction.service.ts b/src/services/webCryptoFunction.service.ts index 0c6c23d4e9..aa8d3f47ae 100644 --- a/src/services/webCryptoFunction.service.ts +++ b/src/services/webCryptoFunction.service.ts @@ -47,9 +47,9 @@ export class WebCryptoFunctionService implements CryptoFunctionService { return await this.subtle.deriveBits(pbkdf2Params, impKey, wcLen); } - async hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512'): Promise { - if ((this.isEdge || this.isIE) && algorithm === 'sha1') { - const md = forge.md.sha1.create(); + async hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5'): Promise { + if (((this.isEdge || this.isIE) && algorithm === 'sha1') || algorithm === 'md5') { + const md = algorithm === 'md5' ? forge.md.md5.create() : forge.md.sha1.create(); const valueBytes = this.toByteString(value); md.update(valueBytes, 'raw'); return Utils.fromByteStringToArray(md.digest().data).buffer; @@ -263,7 +263,10 @@ export class WebCryptoFunctionService implements CryptoFunctionService { return bytes; } - private toWebCryptoAlgorithm(algorithm: 'sha1' | 'sha256' | 'sha512'): string { + private toWebCryptoAlgorithm(algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5'): string { + if (algorithm === 'md5') { + throw new Error('MD5 is not supported in WebCrypto.'); + } return algorithm === 'sha1' ? 'SHA-1' : algorithm === 'sha256' ? 'SHA-256' : 'SHA-512'; } }