mirror of
https://github.com/vacp2p/waku-ts.git
synced 2026-01-08 21:07:59 -05:00
generateSymKeyFromPassword and use compressed public keys as key.id
This commit is contained in:
@@ -62,7 +62,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"basic-provider": "^1.1.0",
|
"basic-provider": "^1.1.0",
|
||||||
"eccrypto-js": "^5.2.0",
|
"eccrypto-js": "^5.3.0",
|
||||||
"localStorage": "^1.0.4"
|
"localStorage": "^1.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
generateKeyPair,
|
generateKeyPair,
|
||||||
bufferToHex,
|
bufferToHex,
|
||||||
getPublic,
|
|
||||||
hexToBuffer,
|
hexToBuffer,
|
||||||
generatePrivate,
|
randomBytes,
|
||||||
|
pbkdf2,
|
||||||
|
utf8ToBuffer,
|
||||||
|
removeHexPrefix,
|
||||||
|
getPublicCompressed,
|
||||||
} from "eccrypto-js";
|
} from "eccrypto-js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -16,8 +19,7 @@ import {
|
|||||||
JsonRpcRequest,
|
JsonRpcRequest,
|
||||||
} from "../typings";
|
} from "../typings";
|
||||||
import { STORE_KEYS_ID, WAKU_PREFIX } from "../constants";
|
import { STORE_KEYS_ID, WAKU_PREFIX } from "../constants";
|
||||||
import { uuid, getFirstMatch } from "../helpers";
|
import { getFirstMatch, isKeyPair, isSymKey } from "../helpers";
|
||||||
import { isKeyPair, isSymKey } from "../helpers/validators";
|
|
||||||
|
|
||||||
export class WakuKeyring implements IWakuKeyring {
|
export class WakuKeyring implements IWakuKeyring {
|
||||||
private keyMap: KeyMap = {};
|
private keyMap: KeyMap = {};
|
||||||
@@ -77,7 +79,7 @@ export class WakuKeyring implements IWakuKeyring {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async newSymKey(): Promise<string> {
|
public async newSymKey(): Promise<string> {
|
||||||
const key = this.genSymKey();
|
const key = await this.genSymKey();
|
||||||
await this.addKey(key);
|
await this.addKey(key);
|
||||||
return key.id;
|
return key.id;
|
||||||
}
|
}
|
||||||
@@ -86,7 +88,7 @@ export class WakuKeyring implements IWakuKeyring {
|
|||||||
let key = this.getMatchingKey("symKey", symKey);
|
let key = this.getMatchingKey("symKey", symKey);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
key = {
|
key = {
|
||||||
id: uuid(),
|
id: this.getKeyId(symKey),
|
||||||
symKey,
|
symKey,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -94,9 +96,8 @@ export class WakuKeyring implements IWakuKeyring {
|
|||||||
return key.id;
|
return key.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async generateSymKeyFromPassword(): Promise<string> {
|
public async generateSymKeyFromPassword(password: string): Promise<string> {
|
||||||
// TODO: needs to accept optional "password" argument
|
const key = await this.genSymKey(password);
|
||||||
const key = this.genSymKey();
|
|
||||||
await this.addKey(key);
|
await this.addKey(key);
|
||||||
return key.id;
|
return key.id;
|
||||||
}
|
}
|
||||||
@@ -128,28 +129,39 @@ export class WakuKeyring implements IWakuKeyring {
|
|||||||
private genKeyPair(prvKey?: string): KeyPair {
|
private genKeyPair(prvKey?: string): KeyPair {
|
||||||
if (prvKey) {
|
if (prvKey) {
|
||||||
return {
|
return {
|
||||||
id: uuid(),
|
id: this.getKeyId(prvKey),
|
||||||
pubKey: bufferToHex(getPublic(hexToBuffer(prvKey)), true),
|
pubKey: this.getPubKey(prvKey),
|
||||||
prvKey,
|
prvKey,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const key = generateKeyPair();
|
const key = generateKeyPair();
|
||||||
return {
|
return {
|
||||||
id: uuid(),
|
id: this.getKeyId(bufferToHex(key.privateKey)),
|
||||||
pubKey: bufferToHex(key.publicKey, true),
|
pubKey: bufferToHex(key.publicKey, true),
|
||||||
prvKey: bufferToHex(key.privateKey, true),
|
prvKey: bufferToHex(key.privateKey, true),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private genSymKey(): SymKey {
|
private async genSymKey(password?: string): Promise<SymKey> {
|
||||||
const symKey = generatePrivate();
|
const symKey =
|
||||||
|
typeof password === "string"
|
||||||
|
? await pbkdf2(utf8ToBuffer(password))
|
||||||
|
: randomBytes(32);
|
||||||
return {
|
return {
|
||||||
id: uuid(),
|
id: this.getKeyId(bufferToHex(symKey)),
|
||||||
symKey: bufferToHex(symKey, true),
|
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> {
|
private async loadKeys(): Promise<void> {
|
||||||
this.keyMap = (await this.store.get(STORE_KEYS_ID)) || {};
|
this.keyMap = (await this.store.get(STORE_KEYS_ID)) || {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export * from "./json";
|
export * from "./json";
|
||||||
export * from "./local";
|
export * from "./local";
|
||||||
export * from "./misc";
|
export * from "./misc";
|
||||||
export * from "./uuid";
|
export * from "./validators";
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ export interface IWakuKeyring extends IWakuController {
|
|||||||
getPrivateKey(id: string): Promise<string>;
|
getPrivateKey(id: string): Promise<string>;
|
||||||
newSymKey(): Promise<string>;
|
newSymKey(): Promise<string>;
|
||||||
addSymKey(symKey: string): Promise<string>;
|
addSymKey(symKey: string): Promise<string>;
|
||||||
generateSymKeyFromPassword(): Promise<string>;
|
generateSymKeyFromPassword(password: string): Promise<string>;
|
||||||
hasSymKey(id: string): Promise<boolean>;
|
hasSymKey(id: string): Promise<boolean>;
|
||||||
getSymKey(id: string): Promise<string>;
|
getSymKey(id: string): Promise<string>;
|
||||||
deleteSymKey(id: string): Promise<boolean>;
|
deleteSymKey(id: string): Promise<boolean>;
|
||||||
|
|||||||
@@ -57,4 +57,24 @@ describe("Waku", () => {
|
|||||||
});
|
});
|
||||||
expect(prvKey).toBeTruthy();
|
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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
11
yarn.lock
11
yarn.lock
@@ -2705,15 +2705,16 @@ ecc-jsbn@~0.1.1:
|
|||||||
jsbn "~0.1.0"
|
jsbn "~0.1.0"
|
||||||
safer-buffer "^2.1.0"
|
safer-buffer "^2.1.0"
|
||||||
|
|
||||||
eccrypto-js@^5.2.0:
|
eccrypto-js@^5.3.0:
|
||||||
version "5.2.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.2.0.tgz#eb3b36e9978d316fedf50be46492bb0d3e240cf5"
|
resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.3.0.tgz#67417e43691ad78992249097ac558776c9ac5ff3"
|
||||||
integrity sha512-pPb6CMapJ1LIzjLWxMqlrnfaEFap7qkk9wcO/b4AVSdxBQYlpOqvlPpq5SpUI4FdmfdhVD34AjN47fM8fryC4A==
|
integrity sha512-fCPIHNr/RDSCNY9NKkrSsjkurb6Rw/d5TYVdzjJeA3E+HcF+DdaWAvhDdsAcBOGUJ6Ygs8o6b4imuvhx9t7o+Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
aes-js "3.1.2"
|
aes-js "3.1.2"
|
||||||
enc-utils "2.1.0"
|
enc-utils "2.1.0"
|
||||||
hash.js "1.1.7"
|
hash.js "1.1.7"
|
||||||
js-sha3 "0.8.0"
|
js-sha3 "0.8.0"
|
||||||
|
pbkdf2 "^3.0.17"
|
||||||
randombytes "2.1.0"
|
randombytes "2.1.0"
|
||||||
secp256k1 "3.8.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"
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||||
|
|
||||||
pbkdf2@^3.0.3:
|
pbkdf2@^3.0.17, pbkdf2@^3.0.3:
|
||||||
version "3.0.17"
|
version "3.0.17"
|
||||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
|
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
|
||||||
integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==
|
integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==
|
||||||
|
|||||||
Reference in New Issue
Block a user