v1.0.0
This commit is contained in:
		
							parent
							
								
									2f009ee9a6
								
							
						
					
					
						commit
						8fa54ad4d7
					
				
							
								
								
									
										55
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								README.md
									
									
									
									
									
								
							@ -27,10 +27,11 @@ RSA.generateKeypair(bitlen, exp, options).then(function (keypair) {
 | 
			
		||||
 | 
			
		||||
`console.log(keypair)`:
 | 
			
		||||
```javascript
 | 
			
		||||
// http://crypto.stackexchange.com/questions/6593/what-data-is-saved-in-rsa-private-key
 | 
			
		||||
 | 
			
		||||
{ publicKeyPem: '/*base64 pem-encoded string*/'
 | 
			
		||||
, privateKeyPem: '/*base64 pem-encoded string*/'
 | 
			
		||||
{ publicKeyPem: '-----BEGIN RSA PUBLIC KEY-----\n/*base64 pem-encoded string*/'
 | 
			
		||||
, privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\n/*base64 pem-encoded string*/'
 | 
			
		||||
 | 
			
		||||
  // http://crypto.stackexchange.com/questions/6593/what-data-is-saved-in-rsa-private-key
 | 
			
		||||
, privateKeyJwk: {
 | 
			
		||||
    kty: "RSA"
 | 
			
		||||
  , n: '/*base64 modulus n = pq*/'
 | 
			
		||||
@ -47,8 +48,11 @@ RSA.generateKeypair(bitlen, exp, options).then(function (keypair) {
 | 
			
		||||
  , n: /*base64 modulus n = pq*/
 | 
			
		||||
  , e: /base64 exponent (usually 65537)*/
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
, _ursa: /*undefined or intermediate ursa object*/
 | 
			
		||||
, _ursaPublic: /*undefined or intermediate ursa object*/
 | 
			
		||||
, _forge: /*undefined or intermediate forge object*/
 | 
			
		||||
, _forgePublic: /*undefined or intermediate forge object*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NOTE: this object is JSON safe as _ursa and _forge will be ignored
 | 
			
		||||
@ -59,7 +63,12 @@ API
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
* `RSA.generateKeypair(bitlen, exp, options, cb)`
 | 
			
		||||
* `RSA.importPemPrivateKey(privatePem)`
 | 
			
		||||
* `RSA.exportPrivatePem(keypair)`
 | 
			
		||||
* `RSA.exportPublicPem(keypair)`
 | 
			
		||||
* `RSA.exportPrivateJwk(keypair)`
 | 
			
		||||
* `RSA.exportPublicJwk(keypair)`
 | 
			
		||||
 | 
			
		||||
`keypair` can be any object with any of these keys `publicKeyPem, privateKeyPem, publicKeyJwk, privateKeyJwk`
 | 
			
		||||
 | 
			
		||||
### RSA.generateKeypair(bitlen, exp, options, cb)
 | 
			
		||||
 | 
			
		||||
@ -85,41 +94,3 @@ RSA.generateKeypair(1024, 65537, { pem: false, public: false, internal: false },
 | 
			
		||||
, fingerprint: false  // NOT IMPLEMENTED (RSA key fingerprint)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### RSA.import(keypair, options, cb)
 | 
			
		||||
 | 
			
		||||
Import a private key or public key as PEM, JWK, and/or internal formats
 | 
			
		||||
 | 
			
		||||
`rsa`:
 | 
			
		||||
```javascript
 | 
			
		||||
{ publicKeyPem: '...'
 | 
			
		||||
, privateKeyPem: '...'
 | 
			
		||||
, privateKeyJwk: { /*...*/ }
 | 
			
		||||
, publicKeyJwk: { /*...*/ }
 | 
			
		||||
, _ursa: '[Object object]'
 | 
			
		||||
, _forge: '[Object object]'
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`options`:
 | 
			
		||||
```
 | 
			
		||||
// same as above, except the following are also added
 | 
			
		||||
{ private: true   // export private key
 | 
			
		||||
                  // (as opposed to using a private key
 | 
			
		||||
                  // solely to export the public key)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Other
 | 
			
		||||
 | 
			
		||||
(the code is there, but they aren't exposed yet)
 | 
			
		||||
 | 
			
		||||
* `toStandardB64(certbuf.toString('base64'))`
 | 
			
		||||
* `thumbprint(publicPem)`
 | 
			
		||||
* `generateCsr(privateKeyPem, ['example.com'])`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    cert = toStandardB64(certbuf.toString('base64'))
 | 
			
		||||
    cert=cert.match(/.{1,64}/g).join('\n');
 | 
			
		||||
    return '-----BEGIN CERTIFICATE-----\n'+cert+'\n-----END CERTIFICATE-----';
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								lib/node.js
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lib/node.js
									
									
									
									
									
								
							@ -8,12 +8,12 @@
 | 
			
		||||
var cryptoc = module.exports;
 | 
			
		||||
var rsaExtra = require('./rsa-extra');
 | 
			
		||||
var rsaForge = require('./rsa-forge');
 | 
			
		||||
var ursac;
 | 
			
		||||
var rsaUrsa;
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  ursac = require('./rsa-ursa');
 | 
			
		||||
  rsaUrsa = require('./rsa-ursa');
 | 
			
		||||
} catch(e) {
 | 
			
		||||
  ursac = {};
 | 
			
		||||
  rsaUrsa = {};
 | 
			
		||||
  // things will run a little slower on keygen, but it'll work on windows
 | 
			
		||||
  // (but don't try this on raspberry pi - 20+ MINUTES key generation)
 | 
			
		||||
}
 | 
			
		||||
@ -23,15 +23,9 @@ try {
 | 
			
		||||
// * ursa
 | 
			
		||||
// * forge extra (the new one aimed to be less-forgey)
 | 
			
		||||
// * forge (fallback)
 | 
			
		||||
Object.keys(ursac).forEach(function (key) {
 | 
			
		||||
Object.keys(rsaUrsa).forEach(function (key) {
 | 
			
		||||
  if (!cryptoc[key]) {
 | 
			
		||||
    cryptoc[key] = ursac[key];
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Object.keys(rsaExtra).forEach(function (key) {
 | 
			
		||||
  if (!cryptoc[key]) {
 | 
			
		||||
    cryptoc[key] = rsaExtra[key];
 | 
			
		||||
    cryptoc[key] = rsaUrsa[key];
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -40,3 +34,9 @@ Object.keys(rsaForge).forEach(function (key) {
 | 
			
		||||
    cryptoc[key] = rsaForge[key];
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Object.keys(rsaExtra).forEach(function (key) {
 | 
			
		||||
  if (!cryptoc[key]) {
 | 
			
		||||
    cryptoc[key] = rsaExtra[key];
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										129
									
								
								lib/rsa-extra.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								lib/rsa-extra.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
//var crypto = require('crypto');
 | 
			
		||||
var forge = require('node-forge');
 | 
			
		||||
 | 
			
		||||
function binstrToB64(binstr) {
 | 
			
		||||
  return new Buffer(binstr, 'binary').toString('base64');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  importPemPrivateKey: function(pem) {
 | 
			
		||||
    var key = forge.pki.privateKeyFromPem(pem);
 | 
			
		||||
    return {
 | 
			
		||||
      privateKey: exportPrivateKey(key),
 | 
			
		||||
      publicKey: exportPublicKey(key)
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  importPemCertificate: function(pem) {
 | 
			
		||||
    return forge.pki.certificateFromPem(pem);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  privateKeyToPem: function(privateKey) {
 | 
			
		||||
    var priv = importPrivateKey(privateKey);
 | 
			
		||||
    return forge.pki.privateKeyToPem(priv);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  certificateToPem: function(certificate) {
 | 
			
		||||
    var derCert = base64ToBytes(certificate);
 | 
			
		||||
    var cert = forge.pki.certificateFromAsn1(forge.asn1.fromDer(derCert));
 | 
			
		||||
    return forge.pki.certificateToPem(cert);
 | 
			
		||||
  },
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
var extrac = module.exports = {
 | 
			
		||||
  //
 | 
			
		||||
  // internals
 | 
			
		||||
  //
 | 
			
		||||
  _forgeToPrivateJwk: function (keypair) {
 | 
			
		||||
    var k = keypair._forge.privateKey;
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      kty: "RSA"
 | 
			
		||||
    , n: binstrToB64(k.n.toByteArray())
 | 
			
		||||
    , e: binstrToB64(k.e.toByteArray())
 | 
			
		||||
    , d: binstrToB64(k.d.toByteArray())
 | 
			
		||||
    , p: binstrToB64(k.p.toByteArray())
 | 
			
		||||
    , q: binstrToB64(k.q.toByteArray())
 | 
			
		||||
    , dp: binstrToB64(k.dP.toByteArray())
 | 
			
		||||
    , dq: binstrToB64(k.dQ.toByteArray())
 | 
			
		||||
    , qi: binstrToB64(k.qInv.toByteArray())
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
, _forgeToPublicJwk: function (keypair) {
 | 
			
		||||
    var k = keypair._forge.privateKey || keypair._forge.publicKey;
 | 
			
		||||
    return {
 | 
			
		||||
      kty: "RSA"
 | 
			
		||||
    , n: binstrToB64(k.n.toByteArray())
 | 
			
		||||
    , e: binstrToB64(k.e.toByteArray())
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Export JWK
 | 
			
		||||
  //
 | 
			
		||||
, exportPrivateJwk: function (keypair) {
 | 
			
		||||
    var hasUrsaPrivate = keypair._ursa && true;
 | 
			
		||||
    var hasPrivatePem = keypair.privateKeyPem && true;
 | 
			
		||||
    var hasForgePrivate = keypair._forge && keypair._forge.privateKey && true;
 | 
			
		||||
 | 
			
		||||
    if (keypair.privateKeyJwk) {
 | 
			
		||||
      return keypair.privateKeyJwk;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!hasForgePrivate) {
 | 
			
		||||
      if (hasUrsaPrivate && !hasPrivatePem) {
 | 
			
		||||
        keypair.privateKeyPem = keypair._ursa.toPrivatePem().toString('ascii');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (keypair.privateKeyPem) {
 | 
			
		||||
        keypair._forge = { privateKey: forge.pki.privateKeyFromPem(keypair.privateKeyPem) };
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (keypair._forge && keypair._forge.privateKey) {
 | 
			
		||||
      return extrac._forgeToPrivateJwk(keypair);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw new Error("None of privateKeyPem, _ursa, _forge, or privateKeyJwk found. No way to export private key Jwk");
 | 
			
		||||
  }
 | 
			
		||||
, exportPublicJwk: function (keypair) {
 | 
			
		||||
    var hasUrsaPublic = (keypair._ursa || keypair._ursaPublic) && true;
 | 
			
		||||
    var hasPublicPem = (keypair.privateKeyPem || keypair.publicKeyPem) && true;
 | 
			
		||||
    var hasForgePublic = keypair._forge && true;
 | 
			
		||||
 | 
			
		||||
    if (keypair.publicKeyJwk) {
 | 
			
		||||
      return keypair.publicKeyJwk;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (keypair.privateKeyJwk) {
 | 
			
		||||
      return {
 | 
			
		||||
        kty: 'RSA'
 | 
			
		||||
      , n: keypair.privateKeyJwk.n
 | 
			
		||||
      , e: keypair.privateKeyJwk.e
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!hasForgePublic) {
 | 
			
		||||
      if (hasUrsaPublic && !hasPublicPem) {
 | 
			
		||||
        keypair.publicKeyPem = (keypair._ursa || keypair._ursaPublic).toPublicPem().toString('ascii');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (keypair.publicKeyPem) {
 | 
			
		||||
        keypair._forge = { privateKey: forge.pki.publicKeyFromPem(keypair.publicKeyPem) };
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (keypair._forge && keypair._forge.privateKey) {
 | 
			
		||||
      return extrac._forgeToPublicJwk(keypair);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw new Error("None of publicKeyPem privateKeyPem, _ursa, _forge, publicKeyJwk, or privateKeyJwk found. No way to export private key Jwk");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
@ -41,6 +41,7 @@ var forgec = module.exports = {
 | 
			
		||||
, _privateJwkToComponents: function (jwk) {
 | 
			
		||||
    var components = [];
 | 
			
		||||
 | 
			
		||||
    // [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
 | 
			
		||||
    [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
 | 
			
		||||
      components.push(new forgec._base64tobin(jwk[key]));
 | 
			
		||||
    });
 | 
			
		||||
@ -76,7 +77,7 @@ var forgec = module.exports = {
 | 
			
		||||
  //
 | 
			
		||||
  // Export Public / Private PEMs
 | 
			
		||||
  //
 | 
			
		||||
, exportPrivateKeyPem: function (keypair) {
 | 
			
		||||
, exportPrivatePem: function (keypair) {
 | 
			
		||||
    if (keypair.privateKeyPem) {
 | 
			
		||||
      return keypair.privateKeyPem;
 | 
			
		||||
    }
 | 
			
		||||
@ -97,7 +98,7 @@ var forgec = module.exports = {
 | 
			
		||||
 | 
			
		||||
    throw new Error("None of privateKeyPem, _forge, or privateKeyJwk found. No way to export private key PEM");
 | 
			
		||||
  }
 | 
			
		||||
, exportPublicKeyPem: function (keypair) {
 | 
			
		||||
, exportPublicPem: function (keypair) {
 | 
			
		||||
    if (keypair.publicKeyPem) {
 | 
			
		||||
      return keypair.publicKeyPem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ var ursac = module.exports = {
 | 
			
		||||
  //
 | 
			
		||||
  // Export Public / Private PEMs
 | 
			
		||||
  //
 | 
			
		||||
, exportPrivateKeyPem: function (keypair) {
 | 
			
		||||
, exportPrivatePem: function (keypair) {
 | 
			
		||||
    if (keypair.privateKeyPem) {
 | 
			
		||||
      return keypair.privateKeyPem;
 | 
			
		||||
    }
 | 
			
		||||
@ -72,7 +72,7 @@ var ursac = module.exports = {
 | 
			
		||||
 | 
			
		||||
    throw new Error("None of privateKeyPem, _ursa, or privateKeyJwk found. No way to export private key PEM");
 | 
			
		||||
  }
 | 
			
		||||
, exportPublicKeyPem: function (keypair) {
 | 
			
		||||
, exportPublicPem: function (keypair) {
 | 
			
		||||
    if (keypair.publicKeyPem) {
 | 
			
		||||
      return keypair.publicKeyPem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								node.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								node.js
									
									
									
									
									
								
							@ -43,18 +43,11 @@ function create(deps) {
 | 
			
		||||
 | 
			
		||||
    options = options || NOBJ;
 | 
			
		||||
 | 
			
		||||
    RSA._internal.generateKeypair(length, exponent, options, function (keys) {
 | 
			
		||||
    RSA._internal.generateKeypair(length, exponent, options, function (err, keys) {
 | 
			
		||||
      if (false !== options.jwk || options.thumbprint) {
 | 
			
		||||
        keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keys);
 | 
			
		||||
        if (options.public) {
 | 
			
		||||
          keypair.publicKeyJwk = RSA._internal.exportPublicJwk(keys);
 | 
			
		||||
          /*
 | 
			
		||||
          return {
 | 
			
		||||
            kty: keypair.privateKeyJwk.kty
 | 
			
		||||
          , n: keypair.privateKeyJwk.n
 | 
			
		||||
          , e: keypair.privateKeyJwk.e
 | 
			
		||||
          };
 | 
			
		||||
          */
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -81,6 +74,12 @@ function create(deps) {
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  RSA.exportPrivateKey = RSA._internal.exportPrivatePem;
 | 
			
		||||
  RSA.exportPublicKey = RSA._internal.exportPublicPem;
 | 
			
		||||
 | 
			
		||||
  RSA.exportPrivateJwk = RSA._internal.exportPrivateJwk;
 | 
			
		||||
  RSA.exportPublicJwk = RSA._internal.exportPublicJwk;
 | 
			
		||||
 | 
			
		||||
  return RSA;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ var RSA = require('../').RSA;
 | 
			
		||||
console.log('RSA');
 | 
			
		||||
console.log(RSA);
 | 
			
		||||
 | 
			
		||||
RSA.generateKeypair(null, null, null, function (keys) {
 | 
			
		||||
RSA.generateKeypair(null, null, null, function (err, keys) {
 | 
			
		||||
  console.log('');
 | 
			
		||||
  console.log('keys');
 | 
			
		||||
  console.log(keys);
 | 
			
		||||
@ -33,10 +33,22 @@ RSA.generateKeypair(null, null, null, function (keys) {
 | 
			
		||||
  , internal: true      // preserve internal intermediate formats (_ursa, _forge)
 | 
			
		||||
  , thumbprint: true    // JWK sha256 thumbprint
 | 
			
		||||
  };
 | 
			
		||||
  RSA.generateKeypair(512, 65537, options, function (keys) {
 | 
			
		||||
  RSA.generateKeypair(512, 65537, options, function (err, keys) {
 | 
			
		||||
    console.log('');
 | 
			
		||||
    console.log('keys');
 | 
			
		||||
    console.log(keys);
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
       keys.publicKeyJwk
 | 
			
		||||
    || keys.privateKeyPem
 | 
			
		||||
    || keys.publicKeyPem
 | 
			
		||||
    || keys.thumbprint
 | 
			
		||||
    || keys._ursa
 | 
			
		||||
    || keys._forge
 | 
			
		||||
    ) {
 | 
			
		||||
      console.error(keys);
 | 
			
		||||
      throw new Error("Got unexpected keys");
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user