<p>Apparently(I haven't run your code) it doesn't seem to have any major flaw, except that ECB mode is not recommended for AES(CBC is good, and GCM is better).</p>
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki" rel="nofollow noreferrer">BIP38</a> could be a good reference for your purpose.</p>

CC BY-SA 4.0
2024-07-26T12:37:43.587Z
Thanks for the input! (I wasn't aware of BIP38, seems very useful)
user155123
CC BY-SA 4.0
2024-07-26T05:00:57.020Z
2024-07-26T05:00:57.020Z
Hyunhum Cho
<p>I would like to add 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.</p>
<p>I'm considering this approach:</p>
<ol>
<li>convert the seed phrase to entropy</li>
<li>encrypt entropy with a password</li>
<li>convert the encrypted-entropy to a new seed phrase (which is longer)</li>
<li>store the encrypted seed phrase</li>
</ol>
<p>Then, I do the reverse to retrieve the initial seed phrase when needed.</p>
<p>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.</p>
<p>I wonder if there is any major flaw in my approach or my code.</p>
<p>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.</p>
<pre class="lang-js prettyprint-override"><code>
import crypto from &quot;crypto&quot;;
import bip39 from &quot;bip39-light&quot;;

const algorithm = &quot;aes-256-ecb&quot;;
const initialVector = null;
const keySize = 32;
const keySalt = &quot;&quot;;

const inputPassword = &quot;&quot;; // password goes here
const inputMnemonic = &quot;&quot;; // 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, &quot;hex&quot;, &quot;hex&quot;);
  encryptedEntropy += cipher.final(&quot;hex&quot;);
  
  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, &quot;hex&quot;, &quot;hex&quot;);
  decryptedEntropy += decipher.final(&quot;hex&quot;);
    
  let decryptedMnemonic = bip39.entropyToMnemonic(decryptedEntropy);
  return decryptedMnemonic;
}
</code></pre>

<security><cryptography><mnemonic-seed>
Is there any major flaw in this seed-phrase encryption approach?
user155123
# Is there any major flaw in this seed-phrase encryption approach?

(Asked by: username_0 on 2024-07-25)

I would like to add 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, I do the reverse to retrieve the initial seed phrase when needed.
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;
}

**Tags:** security, cryptography, mnemonic-seed


---

## 1 answers

### Answer by username_1 on 2024-07-26. Score: 0

Apparently(I haven't run your code) it doesn't seem to have any major flaw, except that ECB mode is not recommended for AES(CBC is good, and GCM is better).

[BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) could be a good reference for your purpose.

> **Comments:**
> **username_0**: Thanks for the input! (I wasn't aware of BIP38, seems very useful)  

---

