Save identity in local storage (#80)

This commit is contained in:
Szymon Szlachtowicz 2021-10-18 14:57:31 +02:00 committed by GitHub
parent 1ac0ebca18
commit a34dbeeb32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 2 deletions

View File

@ -6,6 +6,7 @@ import { ApplicationMetadataMessage } from "status-communities/dist/cjs";
import { uintToImgUrl } from "../helpers/uintToImgUrl";
import { ChatMessage } from "../models/ChatMessage";
import { loadIdentity, saveIdentity } from "../utils/identityStorage";
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
@ -136,8 +137,13 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
useEffect(() => {
const createMessenger = async () => {
const identity = Identity.generate();
// Test password for now
// Need design for password input
let identity = await loadIdentity("test");
if (!identity) {
identity = Identity.generate();
await saveIdentity(identity, "test");
}
const messenger = await Messenger.create(identity, {
libp2p: {
config: {

View File

@ -0,0 +1,86 @@
import { bufToHex, hexToBuf } from "js-waku/build/main/lib/utils";
import { Identity } from "status-communities/dist/cjs";
export async function saveIdentity(identity: Identity, password: string) {
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrapKey = await getWrapKey(password, salt);
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const cipher = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv,
},
wrapKey,
identity.privateKey
);
const data = {
salt: bufToHex(salt),
iv: bufToHex(iv),
cipher: bufToHex(cipher),
};
localStorage.setItem("cipherIdentity", JSON.stringify(data));
}
export async function loadIdentity(
password: string
): Promise<Identity | undefined> {
const str = localStorage.getItem("cipherIdentity");
if (!str) return;
const data = JSON.parse(str);
const salt = hexToBuf(data.salt);
const iv = hexToBuf(data.iv);
const cipher = hexToBuf(data.cipher);
return await decryptIdentity(salt, iv, cipher, password);
}
async function getWrapKey(password: string, salt: Uint8Array) {
const enc = new TextEncoder();
const keyMaterial = await window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"]
);
return await window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
}
async function decryptIdentity(
salt: Buffer,
iv: Buffer,
cipherKeyPair: Buffer,
password: string
): Promise<Identity | undefined> {
const key = await getWrapKey(password, salt);
try {
const decrypted = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
cipherKeyPair
);
return new Identity(new Uint8Array(decrypted));
} catch (e) {
return;
}
}