Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Forge Crypto Library: recreating public and private keys for later reuse

In the Forge Javascript Cryptography Library, I am having a difficult time figuring out how to reconstruct a the private and public keys after I have used them. I have attempted the following:

var rsa = forge.pki.rsa;
var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001});
var ct = keypair.publicKey.encrypt("Arbitrary Message Here");
keypair.privateKey.decrypt(ct);

Which outputs: "Arbitrary Message Here" as expected. I have tried to reconstruct the public key this way:

var nVal = JSON.stringify(keypair.publicKey.n);
var eVal = JSON.stringify(keypair.publicKey.e);
var nwRsa = rsa.setPublicKey(JSON.parse(nHere), JSON.parse(eHere));
var nwCt = nwRsa.encrypt("Arbitrary Message Here"); 

When I try to encrypt the message again, I get an error:

"TypeError: Object #<Object> has no method 'bitLength'"

I'm not sure why though, as I believe I have used the method correctly:

/**
 * Sets an RSA public key from BigIntegers modulus and exponent.
 *
 * @param n the modulus.
 * @param e the exponent.
 *
 * @return the public key.
 */
pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {
  var key = {
    n: n,
    e: e
  };

And I haven't even tried reconstructing the private key yet. I'm not sure what I'm not doing correctly, could anyone please help me? As always thanks in advance!

Additional Afterthough: here are the files I'm importing in my html page, I believe I've resolved all dependency issues, but I just in case (beware, they are not in alphabetical order, but in order of dependency):

<script src="forge/util.js"></script>
<script src="forge/debug.js"></script>
<script src="forge/jsbn.js"></script>
<script src="forge/oids.js"></script>
<script src="forge/asn1.js"></script>
<script src="forge/sha1.js"></script>
<script src="forge/sha256.js"></script>
<script src="forge/md5.js"></script>
<script src="forge/md.js"></script> 
<script src="forge/aes.js"></script>
<script src="forge/prng.js"></script>
<script src="forge/random.js"></script>
<script src="forge/jsbn.js"></script> 
<script src="forge/pkcs1.js"></script>
<script src="forge/rsa.js"></script>

<script src="forge/des.js"></script>
<script src="forge/rc2.js"></script>
<script src="forge/pbe.js"></script>
<script src="forge/pem.js"></script>
<script src="forge/hmac.js"></script>
<script src="forge/pbkdf2.js"></script>
<script src="forge/pkcs7asn1.js"></script>
<script src="forge/pkcs12.js"></script>
<script src="forge/pss.js"></script>
<script src="forge/mgf1.js"></script>
<script src="forge/mgf.js"></script>
<script src="forge/x509.js"></script>
<script src="forge/pki.js"></script>

TL;DR: In Forge, how does one give their public key to someone else, and how should one store their private key for multiple uses?

like image 984
Paul Nelson Baker Avatar asked Nov 19 '13 09:11

Paul Nelson Baker


1 Answers

I was lucky enough to get in contact with the developer by raising an issue on Github. He gave me the correct methods to use, and they all seem to work. Directly quoting, here is the correct usage:

The easiest and most compatible way to transmit public keys or to store private keys is to convert them to PEM format. Private keys may be optionally encrypted when converting them (by using a different method, see below).

Converting a public key to/from PEM:

// convert a Forge public key to PEM-format
var pem = pki.publicKeyToPem(publicKey);

// convert a PEM-formatted public key to a Forge public key
var publicKey = pki.publicKeyFromPem(pem); Converting a private key to/from PEM:

// convert a Forge private key to PEM-format
// (preferred method if you don't want encryption)
var pem = pki.privateKeyToPem(privateKey);

// wraps and encrypts a Forge private key and outputs it in PEM format
// (preferred method if you do want encryption)
var pem = pki.encryptRsaPrivateKey(privateKey, 'password');

// encrypts a Forge private key and outputs it in PEM format using OpenSSL's
// proprietary legacy format + encapsulated PEM headers (DEK-Info)
// (perhaps more compatible with some legacy OpenSSL-based applications)
var pem = pki.encryptRsaPrivateKey(privateKey, 'password', {legacy: true});

// decrypts a PEM-formatted, encrypted private key
var privateKey = pki.decryptRsaPrivateKey(pem, 'password');
like image 105
Paul Nelson Baker Avatar answered Nov 14 '22 22:11

Paul Nelson Baker