'Deterministically generate public/private key from a seed for asymmetric encryption

I am trying to implement a client side method to encrypt data in transit, and the key will be generated from client side with node.js

Right now, i am stuck in a situation that, it seems only RSA key can satisfy the asymmetric encryption for my use case, but the key can only be generated randomly but not deterministically. However, I want the client to be able to regenerate the key from a seed (e.g. a long hash) every time they log on the system, and the key must not be stored on a server.

Is that any workaround or other encryption method that suits my use case? Did some research and came across the npm package below, which said to be able to go the above with RSA.

is there some potential risk for the implementation?



Solution 1:[1]

As I pointed out in another answer, you can use node-forge to create a "rigged" prng that consistently returns an appropriately formatted seed rather than a pseudo-random value.

Code could look like the following, grabbing user's input and generating a long hash from it:

import forge from "node-forge"

const userInput = 'The quick brown fox jumps over the lazy dog'

const md = forge.md.sha256.create();
md.update(userInput);
const seed = md.digest().toHex());

console.log(seed) // output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592

Then creating the PRNG and generating the keys deterministically:

// "Rigged" PRNG
const prng = forge.random.createInstance()
prng.seedFileSync = () => seed

// Deterministic key generation
const { privateKey, publicKey } = forge.pki.rsa.generateKeyPair({ bits: 4096, prng })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luis Antonio Canettoli Ordoñez