feat: add encrypted communication mechanism to the kernel for the private key
This commit is contained in:
parent
6f4b9b7a4a
commit
cbc864c950
|
@ -31,8 +31,10 @@
|
|||
"@lumeweb/libresolver": "^0.1.0-develop.1",
|
||||
"@lumeweb/libweb": "^0.2.0-develop.22",
|
||||
"@lumeweb/tld-enum": "^0.1.0-develop.1",
|
||||
"@noble/ciphers": "^0.1.4",
|
||||
"@peculiar/webcrypto": "^1.4.3",
|
||||
"@scure/bip39": "^1.2.1",
|
||||
"ed25519-keygen": "^0.4.1",
|
||||
"ejs": "^3.1.9",
|
||||
"file-type": "^18.5.0",
|
||||
"is-ipfs": "^8.0.1",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { bytesToHex, hexToBytes } from "@lumeweb/libweb";
|
||||
import {
|
||||
getCommunicationPubKey,
|
||||
setFrontendCommunicationPubkey,
|
||||
} from "../vars.js";
|
||||
import { log } from "../util.js";
|
||||
|
||||
export default function (data: any) {
|
||||
setFrontendCommunicationPubkey(hexToBytes(data));
|
||||
|
||||
return bytesToHex(getCommunicationPubKey());
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { secretbox } from "@noble/ciphers/salsa";
|
||||
import { x25519 } from "@noble/curves/ed25519";
|
||||
import {
|
||||
getCommunicationKey,
|
||||
getFrontendCommunicationPubkey,
|
||||
setLoginComplete,
|
||||
} from "../vars.js";
|
||||
import { saveUserKey } from "../storage.js";
|
||||
import { hexToBytes } from "@lumeweb/libweb";
|
||||
|
||||
export default function (data: any) {
|
||||
const box = secretbox(
|
||||
x25519.getSharedSecret(
|
||||
getCommunicationKey(),
|
||||
getFrontendCommunicationPubkey(),
|
||||
),
|
||||
hexToBytes(data.nonce),
|
||||
);
|
||||
const decryptedData = box.open(hexToBytes(data.data));
|
||||
|
||||
setLoginComplete(false);
|
||||
|
||||
saveUserKey(decryptedData);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
import { Client } from "@lumeweb/libportal";
|
||||
import { x25519 } from "@noble/curves/ed25519";
|
||||
|
||||
let loginComplete = false;
|
||||
let logoutComplete = false;
|
||||
let kernelLoaded = "not yet";
|
||||
let bootloaderPortals: Client[] = [];
|
||||
let communicationKey: Uint8Array;
|
||||
let frontendCommunicationPubKey: Uint8Array;
|
||||
|
||||
var userKey: Uint8Array;
|
||||
|
||||
|
@ -39,3 +42,23 @@ export function getUserKey() {
|
|||
export function setBootloaderPortals(portals: Client[]) {
|
||||
bootloaderPortals = portals;
|
||||
}
|
||||
|
||||
export function getCommunicationKey() {
|
||||
if (!communicationKey) {
|
||||
communicationKey = x25519.utils.randomPrivateKey();
|
||||
}
|
||||
|
||||
return communicationKey;
|
||||
}
|
||||
|
||||
export function getCommunicationPubKey() {
|
||||
return x25519.getPublicKey(getCommunicationKey());
|
||||
}
|
||||
|
||||
export function getFrontendCommunicationPubkey() {
|
||||
return frontendCommunicationPubKey;
|
||||
}
|
||||
|
||||
export function setFrontendCommunicationPubkey(key: Uint8Array) {
|
||||
frontendCommunicationPubKey = key;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
<script>
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import * as bip39 from '@scure/bip39';
|
||||
import { wordlist } from '@scure/bip39/wordlists/english';
|
||||
import * as bip39 from "@scure/bip39";
|
||||
import { wordlist } from "@scure/bip39/wordlists/english";
|
||||
import browser from "webextension-polyfill";
|
||||
|
||||
import '../../styles/global.scss';
|
||||
import lumeLogo from '../../assets/lume-logo.png';
|
||||
import "../../styles/global.scss";
|
||||
import lumeLogo from "../../assets/lume-logo.png";
|
||||
import {
|
||||
bytesToHex,
|
||||
ed25519,
|
||||
hexToBytes,
|
||||
randomBytes,
|
||||
} from "@lumeweb/libweb";
|
||||
import { x25519 } from "@noble/curves/ed25519";
|
||||
import { secretbox } from "@noble/ciphers/salsa";
|
||||
import { HDKey } from "ed25519-keygen/hdkey";
|
||||
const BIP44_PATH = "m/44'/1627'/0'/0'/0'";
|
||||
|
||||
let action;
|
||||
let createAccountStep;
|
||||
|
@ -201,23 +212,54 @@
|
|||
};
|
||||
|
||||
const generatedKeySignIn = () => {
|
||||
const key = generatedKey.join(' ');
|
||||
const seed = generatedKey.join(" ");
|
||||
|
||||
if(!bip39.validateMnemonic(key, wordlist)) {
|
||||
alert('invalid key');
|
||||
if (!bip39.validateMnemonic(seed, wordlist)) {
|
||||
alert("invalid key");
|
||||
return;
|
||||
}
|
||||
|
||||
processSignIn(key);
|
||||
processSignIn(seed);
|
||||
};
|
||||
|
||||
const processSignIn = key => {
|
||||
fadeOut = true;
|
||||
const processSignIn = async (wordSeed) => {
|
||||
const seed = await bip39.mnemonicToSeed(wordSeed);
|
||||
const key = HDKey.fromMasterSeed(seed).derive(BIP44_PATH);
|
||||
|
||||
// use key here
|
||||
let pubKey;
|
||||
let privKey = x25519.utils.randomPrivateKey();
|
||||
|
||||
try {
|
||||
pubKey = await browser.runtime.sendMessage({
|
||||
method: "exchangeCommunicationKeys",
|
||||
data: bytesToHex(x25519.getPublicKey(privKey)),
|
||||
});
|
||||
} catch (e) {
|
||||
alert(`Failed to login: ${e.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pubKey) {
|
||||
alert(`Failed to login: could not get communication key`);
|
||||
return;
|
||||
}
|
||||
pubKey = hexToBytes(pubKey);
|
||||
|
||||
const secret = x25519.getSharedSecret(privKey, pubKey);
|
||||
const nonce = randomBytes(24);
|
||||
const box = secretbox(secret, nonce);
|
||||
const ciphertext = box.seal(key.privateKey);
|
||||
|
||||
await browser.runtime.sendMessage({
|
||||
method: "setLoginKey",
|
||||
data: {
|
||||
data: bytesToHex(ciphertext),
|
||||
nonce: bytesToHex(nonce),
|
||||
},
|
||||
});
|
||||
|
||||
window.setTimeout(() => {
|
||||
window.location.href = '/dashboard.html';
|
||||
window.location.href = "/dashboard.html";
|
||||
}, 1000);
|
||||
};
|
||||
</script>
|
||||
|
|
Reference in New Issue