DEV Community

mibii
mibii

Posted on • Updated on

Building your own Secure Seed Phrase Generator

In previous post we did the NodeJs Vesion of Seed Phrase Generator, here - we will create the browser version of it.

Taking Control: Be Your Own Entropy Master

Today, I want to share my experience in building a secure seed phrase generator - a crucial tool in the world of cryptocurrencies and blockchain technology. This project taught me valuable lessons about cryptography, user interaction, and the importance of randomness in security applications.

The NodeJs Vesion of our Seed Phrase Generator was based on BIP39 library.. Let's try a different approach by implementing the core functionality ourselves without relying on an external library. This will ensure the code works independently.

The Importance of True Randomness

When generating seed phrases, the quality of randomness is paramount. Long time ago, I used JavaScript's Math.random(), but I quickly realized this wasn't secure enough for cryptographic purposes. Here's where I landed:

function generateCustomRandomBytes(byteLength, mouseMoves) {
    const customBytes = new Uint8Array(byteLength);
    window.crypto.getRandomValues(customBytes);

    const mouseHash = new Uint32Array(mouseMoves);
    for (let i = 0; i < byteLength; i++) {
        customBytes[i] ^= mouseHash[i % mouseHash.length] & 0xFF;
    }

    return customBytes;
}
Enter fullscreen mode Exit fullscreen mode

This function combines cryptographically secure random values from window.crypto.getRandomValues() with user-generated entropy from mouse movements. The XOR operation ensures that both sources contribute to the final randomness.

Engaging User Interaction for Added Security

I decided to involve the user in the randomness generation process. By tracking mouse movements, we not only increase entropy but also engage the user, making them an active participant in the security process.

Providing Visual Feedback

Image description

To keep users informed and engaged, I implemented a progress bar that reflects actual mouse movement rather than just elapsed time:

function updateProgressBar() {
    const progress = Math.min((mouseMoves.length / 3) / requiredMoves * 100, 100);
    document.getElementById('progressBar').style.width = progress + '%';

    if (progress >= 100 && collecting) {
        stopRandomCollection();
    } else if (collecting) {
        requestAnimationFrame(updateProgressBar);
    }
}
Enter fullscreen mode Exit fullscreen mode

This approach provides real-time feedback, encouraging users to move their mouse until sufficient entropy is collected.

Protecting Sensitive Data

One crucial lesson was the importance of protecting sensitive data. Initially, I stored the mouse movement data in a global variable, which could potentially be accessed by malicious scripts. I resolved this by using closure:


(function() {
    let mouseMoves = [];
    // ... other variables and functions ...

    function stopRandomCollection() {
        // ... other code ...
        generateSeedPhrase(mouseMoves);
        mouseMoves = []; // Clear sensitive data after use
    }
    // ... rest of the code ...
})();
Enter fullscreen mode Exit fullscreen mode

This approach keeps the sensitive data encapsulated and inaccessible from the global scope.

Running the Seed Phrase Generator Securely

One of the most critical aspects of using a seed phrase generator is ensuring that the process is completely offline and secure. Here's a step-by-step guide on how to run this code safely:

  1. Create a New Text File: Open your preferred text editor (like Notepad on Windows or TextEdit on Mac).
  2. Copy and Paste the Code: Copy the entire HTML code for the seed phrase generator and paste it into this new text file.
  3. Save the File with .html Extension: Save the file with a name like "seed_phrase_generator.html". Make sure to change the file extension from .txt to .html. In most text editors, you can do this by selecting "All Files" in the "Save as type" dropdown and then adding .html to the end of the file name.

Disconnect from the Internet:

Before proceeding, disconnect your computer from the internet. This ensures that no data can be transmitted during the seed phrase generation process.
Run the File in Your Browser:
Double-click the saved .html file to open it in your default web browser. The seed phrase generator should now be running locally on your machine.
Generate Your Seed Phrase:
Follow the on-screen instructions to generate your seed phrase.
Securely Store Your Seed Phrase:
Once generated, write down your seed phrase on paper. Never store it digitally.

Image description

Close the Browser and Delete the File:

After you've securely recorded your seed phrase, close the browser and delete the .html file.

Why Run Offline?

Running this code offline is crucial for several reasons:

Security: It prevents any potential transmission of your seed phrase over the internet.
Privacy: It ensures that no third-party scripts or trackers can interfere with the process.
Integrity: It guarantees that the code runs exactly as intended, without any external modifications.

Remember: Your seed phrase is the key to your digital assets. Always prioritize security when generating and storing it. Running this generator offline is a critical step in protecting your assets.

Balancing Security and User Experience

Building a secure seed phrase generator is more than just writing code. It's about understanding cryptographic principles, valuing user interaction, and always prioritizing security. As developers, projects like these push us to think critically about every line of code we write and its potential implications.

Source code link https://buymeacoffee.com/techmobilebox/e/291196

"Your donation keeps the lights on! (The ones in my brain, mostly.)"

And here is the next step - From Mnemonic to Bitcoin Addresses in JavaScript

Top comments (6)

Collapse
 
mibii profile image
mibii

This guy with a nick "Ravavyr" is trolling, he pretends not to see that my post is a continuation of one of my previous posts, the link to which is indicated at the very beginning. He does not ask any specific questions, but simply mocks.
For others, this mnemonic generators is not for bitcoin wallets only, it is for all that follow the bip39 standard

Collapse
 
ravavyr profile image
Ravavyr

i can so see someone go through all this instead of just writing down a list of words and being done with it....and then they commit it into their public repo lol

Collapse
 
mibii profile image
mibii

You probably didn't read my post. The key point is running the script inside the browser, locally, WITHOUT a server, on any client computer with a browser. That's why the word array is placed inside the file, to avoid fetching data and dancing around the blocked by CORS policy.

Collapse
 
ravavyr profile image
Ravavyr

i read it, it's still too much work when we have simpler solutions. And CORS is hardly a problem worth mentioning. The joke is someone would do all this and still leave themselves vulnerable.

Thread Thread
 
mibii profile image
mibii • Edited

If you say A, then you say B, otherwise it’s empty talk. You call this snippet too “complex”, bring a simple one and we will look at it.
I expected people to ask interesting questions - for example, "Why are there only 2024 words in the dictionary." This was also a question for me, I used to think that a Seed phrase is any set of random words. It turns out no, even among these 2024 words you cannot take just random words, the wallet will not accept them, since the BIP39 standard defines not only a dictionary, but also a checksum. github.com/bitcoin/bips/blob/maste...

Thread Thread
 
ravavyr profile image
Ravavyr

WRITE DOWN A LIST OF WORDS.

THE END.

That is the simple one. You don't need your overcomplicated solution for this.

You're complaining about some specific seed phrases for bitcoin wallets, that's a completely different thing than what your original post was about. You didn't make that clear, that's not on me.
You literally did not mention bitcoin once in your post except for the link all the way at the end. You entire post was incomplete and only about generating a seed and THAT is what i replied to.

Either way, i'm done arguing with you.