get fingerprint crypto method
This commit is contained in:
parent
f355840f3c
commit
ed07c8d01f
|
@ -768,6 +768,11 @@
|
||||||
"callsite": "1.0.0"
|
"callsite": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"big-integer": {
|
||||||
|
"version": "1.6.36",
|
||||||
|
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz",
|
||||||
|
"integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg=="
|
||||||
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
|
||||||
|
@ -776,7 +781,7 @@
|
||||||
},
|
},
|
||||||
"bl": {
|
"bl": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||||
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"readable-stream": "^2.3.5",
|
"readable-stream": "^2.3.5",
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
"@angular/upgrade": "6.1.7",
|
"@angular/upgrade": "6.1.7",
|
||||||
"@aspnet/signalr": "1.0.4",
|
"@aspnet/signalr": "1.0.4",
|
||||||
"@aspnet/signalr-protocol-msgpack": "1.0.4",
|
"@aspnet/signalr-protocol-msgpack": "1.0.4",
|
||||||
|
"big-integer": "1.6.36",
|
||||||
"core-js": "2.5.7",
|
"core-js": "2.5.7",
|
||||||
"electron-log": "2.2.14",
|
"electron-log": "2.2.14",
|
||||||
"electron-updater": "3.0.3",
|
"electron-updater": "3.0.3",
|
||||||
|
|
|
@ -16,6 +16,7 @@ export abstract class CryptoService {
|
||||||
getEncKey: () => Promise<SymmetricCryptoKey>;
|
getEncKey: () => Promise<SymmetricCryptoKey>;
|
||||||
getPublicKey: () => Promise<ArrayBuffer>;
|
getPublicKey: () => Promise<ArrayBuffer>;
|
||||||
getPrivateKey: () => Promise<ArrayBuffer>;
|
getPrivateKey: () => Promise<ArrayBuffer>;
|
||||||
|
getFingerprint: () => Promise<string[]>;
|
||||||
getOrgKeys: () => Promise<Map<string, SymmetricCryptoKey>>;
|
getOrgKeys: () => Promise<Map<string, SymmetricCryptoKey>>;
|
||||||
getOrgKey: (orgId: string) => Promise<SymmetricCryptoKey>;
|
getOrgKey: (orgId: string) => Promise<SymmetricCryptoKey>;
|
||||||
hasKey: () => Promise<boolean>;
|
hasKey: () => Promise<boolean>;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import * as bigInt from 'big-integer';
|
||||||
|
|
||||||
import { EncryptionType } from '../enums/encryptionType';
|
import { EncryptionType } from '../enums/encryptionType';
|
||||||
import { KdfType } from '../enums/kdfType';
|
import { KdfType } from '../enums/kdfType';
|
||||||
|
|
||||||
|
@ -14,6 +16,7 @@ import { ConstantsService } from './constants.service';
|
||||||
|
|
||||||
import { sequentialize } from '../misc/sequentialize';
|
import { sequentialize } from '../misc/sequentialize';
|
||||||
import { Utils } from '../misc/utils';
|
import { Utils } from '../misc/utils';
|
||||||
|
import { EEFLongWordList } from '../misc/wordlist';
|
||||||
|
|
||||||
const Keys = {
|
const Keys = {
|
||||||
key: 'key',
|
key: 'key',
|
||||||
|
@ -163,6 +166,16 @@ export class CryptoService implements CryptoServiceAbstraction {
|
||||||
return this.privateKey;
|
return this.privateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getFingerprint(): Promise<string[]> {
|
||||||
|
const publicKey = await this.getPublicKey();
|
||||||
|
if (publicKey === null) {
|
||||||
|
throw new Error('No public key available.');
|
||||||
|
}
|
||||||
|
const keyFingerprint = await this.cryptoFunctionService.hash(publicKey, 'sha256');
|
||||||
|
const userFingerprint = await this.hkdfExpand(keyFingerprint, Utils.fromUtf8ToArray('USER-ID'), 32);
|
||||||
|
return this.hashPhrase(userFingerprint.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
@sequentialize(() => 'getOrgKeys')
|
@sequentialize(() => 'getOrgKeys')
|
||||||
async getOrgKeys(): Promise<Map<string, SymmetricCryptoKey>> {
|
async getOrgKeys(): Promise<Map<string, SymmetricCryptoKey>> {
|
||||||
if (this.orgKeys != null && this.orgKeys.size > 0) {
|
if (this.orgKeys != null && this.orgKeys.size > 0) {
|
||||||
|
@ -675,6 +688,28 @@ export class CryptoService implements CryptoServiceAbstraction {
|
||||||
return okm;
|
return okm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async hashPhrase(data: ArrayBuffer, minimumEntropy: number = 64) {
|
||||||
|
const wordListLength = EEFLongWordList.length;
|
||||||
|
const entropyPerWord = Math.log(wordListLength) / Math.log(2);
|
||||||
|
let numWords = Math.ceil(minimumEntropy / entropyPerWord);
|
||||||
|
|
||||||
|
const hashBuffer = await this.cryptoFunctionService.pbkdf2(data, '', 'sha256', 50000);
|
||||||
|
const hash = Array.from(new Uint8Array(hashBuffer));
|
||||||
|
const entropyAvailable = hash.length * 4;
|
||||||
|
if (numWords * entropyPerWord > entropyAvailable) {
|
||||||
|
throw new Error('Output entropy of hash function is too small');
|
||||||
|
}
|
||||||
|
|
||||||
|
const phrase: string[] = [];
|
||||||
|
let hashNumber = bigInt.fromArray(hash, 256);
|
||||||
|
while (numWords--) {
|
||||||
|
const remainder = hashNumber.mod(wordListLength);
|
||||||
|
hashNumber = hashNumber.divide(wordListLength);
|
||||||
|
phrase.push(EEFLongWordList[remainder as any]);
|
||||||
|
}
|
||||||
|
return phrase;
|
||||||
|
}
|
||||||
|
|
||||||
private async buildEncKey(key: SymmetricCryptoKey, encKey: ArrayBuffer = null)
|
private async buildEncKey(key: SymmetricCryptoKey, encKey: ArrayBuffer = null)
|
||||||
: Promise<[SymmetricCryptoKey, CipherString]> {
|
: Promise<[SymmetricCryptoKey, CipherString]> {
|
||||||
let encKeyEnc: CipherString = null;
|
let encKeyEnc: CipherString = null;
|
||||||
|
|
Loading…
Reference in New Issue