I am developing chrome extension like metamask for the private Chain. I have generated the keys and using localStorage to store the Keys. But I am not sure whether I am going correct or not for security purpose. I read about the web storages like localStorage,sessionStorage and got confused. Some article says localStorage is safe some says not. Can someone give me a suggestion that which web store should I use and how to encrypt the keys? I know this is a very common question, but for my development which one is suitable?

1 Answer 1


Here is a utility for creating and maintaining accounts in a JSON file.

Each account consists of of a public address, and encrypted private key and a nonce.

The private key is encrypted with a password, so only the password owner can decrypt it.

The nonce doesn't necessarily reflect the current nonce on the network, so it's under your responsibility to increment it (I've found it useful for my use-case, but you can get rid of it if it doesn't help you with yours).

const fs = require("fs");
const assert = require("assert");
const crypto = require("crypto");
const ethereumjsUtil = require("ethereumjs-util");

module.exports = {create, getKey, getAddress, getNonce, setNonce, getUsernames};

function create(username, password) {
    const key = "0x" + crypto.randomBytes(32).toString("hex");
    const address = "0x" + ethereumjsUtil.privateToAddress(key).toString("hex");
    set(username, {address: address, text: encrypt(key, password), nonce: 0}, true);

function getKey(username, password) {
    const account = get(username);
    const key = decrypt(account.text, password);
    try {
        assert(account.address == "0x" + ethereumjsUtil.privateToAddress(key).toString("hex"));
        return key;
    catch (error) {
        throw new Error("wrong password");

function getAddress(username) {
    return get(username).address;

function getNonce(username) {
    return get(username).nonce;

function setNonce(username, nonce) {
    set(username, {...get(username), nonce: nonce}, false);

function getUsernames() {
    return Object.keys(read());

function get(username) {
    return read()[username];

function set(username, account, protect) {
    const accounts = read();
    if (username in accounts && protect)
        throw new Error("account already exists");
    accounts[username] = account;

function encrypt(text, password) {
    const temp = crypto.createCipher("aes-256-ctr", password);
    return temp.update(text, "utf8", "hex") + temp.final("hex");

function decrypt(text, password) {
    const temp = crypto.createDecipher("aes-256-ctr", password);
    return temp.update(text, "hex", "utf8") + temp.final("utf8");

const ACCOUNTS_FILE_NAME = "accounts.json";
try {JSON.parse(fs.readFileSync(ACCOUNTS_FILE_NAME, {encoding: "utf8"}));}
catch (error) {fs.writeFileSync(ACCOUNTS_FILE_NAME, "{}", {encoding: "utf8"});}
function read() {return JSON.parse(fs.readFileSync(ACCOUNTS_FILE_NAME, {encoding: "utf8"}));}
function write(accounts) {fs.writeFileSync(ACCOUNTS_FILE_NAME, JSON.stringify(accounts, null, 4), {encoding: "utf8"});}
  • Thank you @goodvibration for the answer.
    – Varsh
    May 22, 2019 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.