Search code examples
cryptographycryptojsforge

Generate a key pair in "node-forge" using "exponent", "modulus" and "maxdigits"


I'm using "node-forge" to generate a publicKey to use with my AES symmetric key but I don't know how to use the data provided by my backend to create this publicKey. Currently, I receive from an authentication api the following:

e: "10001" n:"c7c5dd235568711a943ebbdacac890ca2cf12c1ab539f77726e8874d2ab4220cf06369358b5eff0425fb17d4f696f741cf04c5ea874415e7f67d118a2e763e641e8675b8f42e9277b3f70f14e4de23fe16f51abdc427490f47e4b28ae3e5eb3563ba797fe90f9b70ba878646b1b297c52ba735827682b67309d38b423e31b50b" maxdigits: "131"

Where "e" is my exponent, "n" is my module and "maxdigits" is the length my BigIntegers are supposed to have.

But when I try something like this:

const keys = forge.pki.rsa.generateKeyPair({ e: res.e, n: res.n });

My backend returns an error. What am I doing wrong?


Solution

  • forge.pki.rsa.generateKeyPair is the wrong method in this context. forge.pki.rsa.generateKeyPair creates a new key pair with random modulus. The first parameter specifies the modulus/key size in bits, the second the exponent ([1] and [2]):

    // var forge = require('node-forge'); // in nodejs-context
    var pki = forge.pki;
    var rsa = forge.pki.rsa;
    
    var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001});
    var pubKeyPEM = pki.publicKeyToPem(keypair.publicKey);
    var privKeyPEM = pki.privateKeyToPem(keypair.privateKey);
    console.log(pubKeyPEM);
    console.log(privKeyPEM);
    

    The forge.pki.rsa.setPublicKey-method is used to generate a public key via modulus and exponent, where the modulus is the first parameter and the exponent is the second parameter ([2]), both of type forge.jsbn.BigInteger ([3]):

    var BigInteger = forge.jsbn.BigInteger;
    var n = new BigInteger('c7c5dd235568711a943ebbdacac890ca2cf12c1ab539f77726e8874d2ab4220cf06369358b5eff0425fb17d4f696f741cf04c5ea874415e7f67d118a2e763e641e8675b8f42e9277b3f70f14e4de23fe16f51abdc427490f47e4b28ae3e5eb3563ba797fe90f9b70ba878646b1b297c52ba735827682b67309d38b423e31b50b', 16);
    var e = new BigInteger('10001', 16);
    var pubKey = rsa.setPublicKey(n, e);
    
    var pubKeyPEM = pki.publicKeyToPem(pubKey)
    console.log(pubKeyPEM); // Check with e.g. https://lapo.it/asn1js/