I would like to add a some security to my seed phrase storage for existing wallets. I’m not trying to make it absolutely secure, just want to make it much more difficult to access my fund if someone finds my seed phrase storage.
I’m considering this approach:
- convert the seed phrase to entropy
- encrypt entropy with a password
- convert the encrypted-entropy to a new seed phrase (which is longer)
- store the encrypted seed phrase
Then, when I want to use seed phrase, I do the reverse to retrieve the initial seed phrase. I have included JS code to demonstrate it below. I used AES CEB without initial vector, and empty key salt so that I don’t need them for decryption.
I wonder if there is any major flaw in my approach or my code.
I understand making my seed phrase storage more secure with a password makes it more likely that I lose access to my seed phrase storage if I forget the password.
import crypto from "crypto";
import bip39 from "bip39-light";
const algorithm = "aes-256-ecb";
const initialVector = null;
const keySize = 32;
const keySalt = "";
const inputPassword = ""; // password goes here
const inputMnemonic = ""; // 12 word seed phrase goes here
// encrypt 12-word input mnemonic to 24-word mnemonic
const encryptedMnemonic = encryptMnemonic(inputMnemonic, inputPassword);
// decrypt 24-word mnemonic back to 12-word mnemonic
const decryptedMnemonic = decryptMnemonic(encryptedMnemonic, inputPassword);
console.log({ inputMnemonic, encryptedMnemonic, decryptedMnemonic });
function encryptMnemonic(mnemonic, password) {
const key = crypto.scryptSync(password, keySalt, keySize);
const entropy = bip39.mnemonicToEntropy(mnemonic);
const cipher = crypto.createCipheriv(algorithm, key, initialVector);
let encryptedEntropy = cipher.update(entropy, "hex", "hex");
encryptedEntropy += cipher.final("hex");
let encryptedMnemonic = bip39.entropyToMnemonic(encryptedEntropy);
return encryptedMnemonic;
}
function decryptMnemonic(mnemonic, password) {
const key = crypto.scryptSync(password, keySalt, keySize);
let encryptedEntropy = bip39.mnemonicToEntropy(mnemonic);
const decipher = crypto.createDecipheriv(algorithm, key, initialVector);
let decryptedEntropy = decipher.update(encryptedEntropy, "hex", "hex");
decryptedEntropy += decipher.final("hex");
let decryptedMnemonic = bip39.entropyToMnemonic(decryptedEntropy);
return decryptedMnemonic;
}