generateSymKeyFromPassword and use compressed public keys as key.id

This commit is contained in:
Pedro Gomes
2020-05-25 20:02:19 +02:00
parent 5ac3fdbcbe
commit 06a76c4d45
7 changed files with 56 additions and 39 deletions

View File

@@ -62,7 +62,7 @@
"dependencies": {
"axios": "^0.19.2",
"basic-provider": "^1.1.0",
"eccrypto-js": "^5.2.0",
"eccrypto-js": "^5.3.0",
"localStorage": "^1.0.4"
}
}

View File

@@ -1,9 +1,12 @@
import {
generateKeyPair,
bufferToHex,
getPublic,
hexToBuffer,
generatePrivate,
randomBytes,
pbkdf2,
utf8ToBuffer,
removeHexPrefix,
getPublicCompressed,
} from "eccrypto-js";
import {
@@ -16,8 +19,7 @@ import {
JsonRpcRequest,
} from "../typings";
import { STORE_KEYS_ID, WAKU_PREFIX } from "../constants";
import { uuid, getFirstMatch } from "../helpers";
import { isKeyPair, isSymKey } from "../helpers/validators";
import { getFirstMatch, isKeyPair, isSymKey } from "../helpers";
export class WakuKeyring implements IWakuKeyring {
private keyMap: KeyMap = {};
@@ -77,7 +79,7 @@ export class WakuKeyring implements IWakuKeyring {
}
public async newSymKey(): Promise<string> {
const key = this.genSymKey();
const key = await this.genSymKey();
await this.addKey(key);
return key.id;
}
@@ -86,7 +88,7 @@ export class WakuKeyring implements IWakuKeyring {
let key = this.getMatchingKey("symKey", symKey);
if (!key) {
key = {
id: uuid(),
id: this.getKeyId(symKey),
symKey,
};
}
@@ -94,9 +96,8 @@ export class WakuKeyring implements IWakuKeyring {
return key.id;
}
public async generateSymKeyFromPassword(): Promise<string> {
// TODO: needs to accept optional "password" argument
const key = this.genSymKey();
public async generateSymKeyFromPassword(password: string): Promise<string> {
const key = await this.genSymKey(password);
await this.addKey(key);
return key.id;
}
@@ -128,28 +129,39 @@ export class WakuKeyring implements IWakuKeyring {
private genKeyPair(prvKey?: string): KeyPair {
if (prvKey) {
return {
id: uuid(),
pubKey: bufferToHex(getPublic(hexToBuffer(prvKey)), true),
id: this.getKeyId(prvKey),
pubKey: this.getPubKey(prvKey),
prvKey,
};
} else {
const key = generateKeyPair();
return {
id: uuid(),
id: this.getKeyId(bufferToHex(key.privateKey)),
pubKey: bufferToHex(key.publicKey, true),
prvKey: bufferToHex(key.privateKey, true),
};
}
}
private genSymKey(): SymKey {
const symKey = generatePrivate();
private async genSymKey(password?: string): Promise<SymKey> {
const symKey =
typeof password === "string"
? await pbkdf2(utf8ToBuffer(password))
: randomBytes(32);
return {
id: uuid(),
id: this.getKeyId(bufferToHex(symKey)),
symKey: bufferToHex(symKey, true),
};
}
private getPubKey(prvKey: string): string {
return bufferToHex(getPublicCompressed(hexToBuffer(prvKey)), true);
}
private getKeyId(prvKey: string): string {
return removeHexPrefix(this.getPubKey(prvKey)).substr(2);
}
private async loadKeys(): Promise<void> {
this.keyMap = (await this.store.get(STORE_KEYS_ID)) || {};
}

View File

@@ -1,4 +1,4 @@
export * from "./json";
export * from "./local";
export * from "./misc";
export * from "./uuid";
export * from "./validators";

View File

@@ -1,16 +0,0 @@
export function uuid(): string {
const result: string = ((a?: any, b?: any) => {
for (
b = a = "";
a++ < 36;
b +=
(a * 51) & 52
? (a ^ 15 ? 8 ^ (Math.random() * (a ^ 20 ? 16 : 4)) : 4).toString(16)
: "-"
) {
// empty
}
return b;
})();
return result;
}

View File

@@ -20,7 +20,7 @@ export interface IWakuKeyring extends IWakuController {
getPrivateKey(id: string): Promise<string>;
newSymKey(): Promise<string>;
addSymKey(symKey: string): Promise<string>;
generateSymKeyFromPassword(): Promise<string>;
generateSymKeyFromPassword(password: string): Promise<string>;
hasSymKey(id: string): Promise<boolean>;
getSymKey(id: string): Promise<string>;
deleteSymKey(id: string): Promise<boolean>;

View File

@@ -57,4 +57,24 @@ describe("Waku", () => {
});
expect(prvKey).toBeTruthy();
});
it("should create symmetric key", async () => {
const symKey = await waku.request({
id: 1,
jsonrpc: "2.0",
method: "waku_newSymKey",
params: [],
});
expect(symKey).toBeTruthy();
});
it("should generate symmetric key from password", async () => {
const symKey = await waku.request({
id: 1,
jsonrpc: "2.0",
method: "waku_generateSymKeyFromPassword",
params: ["password"],
});
expect(symKey).toBeTruthy();
});
});

View File

@@ -2705,15 +2705,16 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
eccrypto-js@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.2.0.tgz#eb3b36e9978d316fedf50be46492bb0d3e240cf5"
integrity sha512-pPb6CMapJ1LIzjLWxMqlrnfaEFap7qkk9wcO/b4AVSdxBQYlpOqvlPpq5SpUI4FdmfdhVD34AjN47fM8fryC4A==
eccrypto-js@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.3.0.tgz#67417e43691ad78992249097ac558776c9ac5ff3"
integrity sha512-fCPIHNr/RDSCNY9NKkrSsjkurb6Rw/d5TYVdzjJeA3E+HcF+DdaWAvhDdsAcBOGUJ6Ygs8o6b4imuvhx9t7o+Q==
dependencies:
aes-js "3.1.2"
enc-utils "2.1.0"
hash.js "1.1.7"
js-sha3 "0.8.0"
pbkdf2 "^3.0.17"
randombytes "2.1.0"
secp256k1 "3.8.0"
@@ -5602,7 +5603,7 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
pbkdf2@^3.0.3:
pbkdf2@^3.0.17, pbkdf2@^3.0.3:
version "3.0.17"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==