AuditService (#2)

* Add AuditService.

* Change sha1 to use Webcrypto.

* Add interface for AuditService.

* Move PwnedPasswodsApi constant outside class.

* Change FromBufferToHex implementation to simpler code.

* Use correct string to array function.

* Change auditService interface to abstract class. Add missing type to utils.
This commit is contained in:
Oscar Hinton 2018-02-28 16:52:35 +01:00 committed by Kyle Spearrin
parent ab00dfd399
commit 1aabb42e47
5 changed files with 49 additions and 0 deletions

View File

@ -0,0 +1,3 @@
export abstract class AuditService {
passwordLeaked: (password: string) => Promise<number>;
}

View File

@ -31,4 +31,5 @@ export abstract class CryptoService {
decrypt: (cipherString: CipherString, key?: SymmetricCryptoKey, outputEncoding?: string) => Promise<string>;
decryptFromBytes: (encBuf: ArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>;
rsaDecrypt: (encValue: string) => Promise<string>;
sha1: (password: string) => Promise<string>;
}

View File

@ -0,0 +1,26 @@
import { CryptoService } from '../abstractions/crypto.service';
const PwnedPasswordsApi = 'https://api.pwnedpasswords.com/range/';
export class AuditService {
constructor(private cryptoService: CryptoService) {
}
async passwordLeaked(password: string): Promise<number> {
const hash = (await this.cryptoService.sha1(password)).toUpperCase();
const response = await fetch(PwnedPasswordsApi + hash.substr(0, 5));
const leakedHashes = await response.text();
const hashEnding = hash.substr(5);
const match = leakedHashes
.split(/\r?\n/)
.find((v) => {
return v.split(':')[0] === hashEnding;
});
return match ? parseInt(match.split(':')[1], 10) : 0;
}
}

View File

@ -452,6 +452,17 @@ export class CryptoService implements CryptoServiceAbstraction {
return b64DecValue;
}
async sha1(password: string): Promise<string> {
const hash = await Crypto.subtle.digest(
{
name: 'SHA-1',
},
UtilsService.fromUtf8ToArray(password),
);
return UtilsService.fromBufferToHex(hash);
}
// Helpers
private async aesEncrypt(plainValue: ArrayBuffer, key: SymmetricCryptoKey): Promise<EncryptedObject> {

View File

@ -125,6 +125,14 @@ export class UtilsService implements UtilsServiceAbstraction {
return decodeURIComponent(escape(encodedString));
}
// Source: Frxstrem, https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex
static fromBufferToHex(buffer: ArrayBuffer): string {
return Array.prototype.map.call(
new Uint8Array(buffer),
(x: number) => ('00' + x.toString(16)).slice(-2),
).join('');
}
static getHostname(uriString: string): string {
if (uriString == null) {
return null;