Creating secure RSA keys using a predetermined seed - a step-by-step guide

Is it possible to utilize a unique set of words as a seed in order to recover a lost private key, similar to how cryptocurrency wallets function? This method can be particularly beneficial for end-to-end encryption among clients, where keys are generated on the client side and only public keys are shared with the server.

Users could potentially regenerate keys offline by re-entering the mnemonic, provided that it is stored securely and offline. The mnemonic seed should contain enough entropy to ensure security.

When looking into generating RSA key pairs using Javascript or Typescript, it's important to consider utilizing maintained libraries rather than outdated Q&A resources.

Answer №1

Solution: bip39 and node-forge

As stated in this insightful answer, the key to achieving this solution lies in understanding the nature of public keys and their vulnerability to offline attacks through dictionary search.

The resulting public key is inherently public, making it susceptible to offline dictionary attacks where possible passwords are attempted until a match is found. This risk is inherent to the desired outcome.

It is recommended that we aim for at least 128 bits of entropy to fend off such attacks in the future, but ultimately, the strength of our mnemonic passphrase is within our control.

1. Generating Mnemonic Passphrase

To begin, we can create a secure mnemonic using the JavaScript implementation of bip-39.

import { generateMnemonic } from "bip39";

const mnemonic = generateMnemonic(256) // Opting for 256 bits for maximum security. Default is 128 bits.

console.log(mnemonic) // Outputs 24 unique words

2. Developing Deterministic PRNG Function

Next, utilize node-forge to generate our encryption keys. The pki.rsa.generateKeyPair function requires a pseudo-random number generator. Our aim is to make this function produce values derived deterministically from the mnemonic, rather than pure randomness.

import { mnemonicToSeed } from "bip39";
import { pki, random } from "node-forge";

const seed = (await mnemonicToSeed(mnemonic)).toString('hex')

const prng = random.createInstance();
prng.seedFileSync = () => seed

3. Key Pair Generation

We can now use the generateKeyPair function with our modified pseudo-random number generator:

const { privateKey, publicKey } = pki.rsa.generateKeyPair({ bits: 4096, prng, workers: 2 })

And there you have it!

With these steps, we have successfully created secure and deterministic RSA keys directly on the client side, all restorable using the same mnemonic passphrase as input. However, be cautious of the risks associated with deterministic keys, ensuring that users do not store their mnemonic online or anywhere easily accessible. It is generally advised to keep a written copy stored in a secure location.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to retrieve the image source using jQuery

<img src="../img/arnold.png" alt="Arnold"> Is there a way to retrieve the absolute path of this image using jQuery? Currently, when I use img.attr("src"), it only returns "../img/arnold.png", but I need it to return something like "http://site.com/ ...

Is there a method to track the number of active onSnapshot listeners from Firestore in my application?

In my app, I am implementing a feature that dynamically removes query onSnapshot listeners and replaces them with new ones. To ensure that resources are properly freed up, I need to test the effectiveness of the unsubscribe function. Unfortunately, I do n ...

Ending a connection to MS SQL server in node.js with mssql library

In my journey to write a node.js script for querying an MSSQL database, I find myself navigating the realm of JavaScript, node.js, and VSCode with limited SQL knowledge. While I have managed to piece together working code, the issue lies in the connection ...

Guide to using a Selector in a mixin in VUE

I'm attempting to create a Mixin that will help me calculate the offsetWidth of an element. Here is my Mixin: export const boxWidth = (selector) => ({ mounted() { selector.addEventListener( 'resize', this.setBoxWidth ); ...

What is the best way to keep the heights of two divs in sync?

Is there a way to make two divs have the same height, even though their content determines their individual heights? I am looking for a solution that doesn't involve using a table or a parent div. I'm new to JavaScript, so I'm hoping there i ...

I'm looking to add multiple markers with multiple info windows using the Google Maps API. How can I achieve this?

Having trouble with the Google Maps API v3? I've set up a map with custom markers, but when clicked they all display the same content in the info window. Can you take a look at my code and help me troubleshoot? Each marker is supposed to link to a spe ...

Using styled-components and typescript to override props

Currently, I am faced with the challenge of using a component that necessitates a specific property to be set. My goal is to style this component with the required property already defined, without having to manually specify it again during rendering. Howe ...

The Redux state fails to start with the default initial state

I'm a newcomer to react-redux. In my reducer, I have the following structure: const initialState = { Low: [ { id: 0, technologyId: 0, technology: '', type: '', ...

Evaluating Angular/Typescript and its capabilities

I seem to be struggling with the concept of how eval functions in TypeScript/Angular. Can someone provide some guidance on how to make eval work in this scenario? Although the logic may not be perfect in this demo program, I just need help figuring out how ...

Error during the production build of Next.js Internationalized Routing: Prerendering page encountered an unexpected issue

The configuration in my next.config.js file looks like this: module.exports = withBundleAnalyzer({ i18n: { locales: ['en', 'es'], defaultLocale: 'en', localeDetection: false, }, ... }); This setup allows for ...

Having trouble with the @keyup event not functioning properly in Vue?

I'm attempting to trigger a method when the enter key is pressed, but for some reason it's not working. Here's the code snippet: <template> <div> <button @click="callEvent" @keyup.enter="callEvent"> Click </button ...

What is the best way to set the v-model property to an object that is constantly changing

I'm in the process of creating a dynamic form that allows users to add additional fields by simply clicking on a button labeled "adicionar condição." The concept is similar to what can be seen in the screenshot below: https://i.stack.imgur.com/Mpmr6 ...

Each time new scripts are loaded, the Angular 13 window.ng.ɵcompilerFacade gets swapped out for a fresh

New Update: After observing the behavior of loading components/modules in my application, I have noticed a conflict arising between window.ng.ɵcompilerFacade and v13 compliance format when switching between Angular versions. The issue occurs when loading ...

Steps for retrieving a table of records with Jquery and sending it to the server through AJAX

Displayed below is a table I have: <table cellspacing="0" rules="all" border="1" id="ContentPlaceHolder1_GridView1" style="border-collapse:collapse;" class="table table-striped"> <tbody> <tr> <th scope="col"> ...

Circular dependency has been detected when using the ESLint with TypeORM

Having two entity typeorm with a bi-directional one-to-one relationship: Departament: @Entity('Departament') export default class Departament { @PrimaryGeneratedColumn() id: string; @Column() departament_name: string; @OneToOne(type ...

Saving Data in an Angular Material Table: A How-to Guide

I have a basic angular material table and I am looking for a way to save the data displayed in each row when a button is clicked. Is it possible to save each row of data as an object and push it to an array? If so, how can I achieve this? <div class=& ...

React Router: Dispatch not triggering when route changes

I have multiple paths that share the same controller: <Route component={Search} path='/accommodation(/:state)(/:region)(/:area)' /> and when the route changes, I trigger the api function within the component: componentWillReceiveProps = ...

Error message 'MODULE_NOT_FOUND' occurs while executing a Docker application

Although I successfully created a docker image, I am encountering issues when trying to run it. This is the command that I am using for running: docker run coderpc/test-server Displayed below is the error message that appears in the console. Error: Canno ...

JavaScript Polling Based on Time

I am currently working on developing an alarm clock feature using the Date() object. My aim is to have a function trigger when the time from the date object matches the time set by the user. Users set their alarms by selecting a specific time, but I' ...

Steady always faces in one direction

I have been working on a Three.JS scene where I need to create an open-topped cylinder with two different colors for its front and inside surfaces. To achieve this, I extended a new material class from THREE.MeshStandardMaterial and made adjustments to th ...