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)`:
|
`console.log(keypair)`:
|
||||||
```javascript
|
```javascript
|
||||||
// http://crypto.stackexchange.com/questions/6593/what-data-is-saved-in-rsa-private-key
|
|
||||||
|
|
||||||
{ publicKeyPem: '/*base64 pem-encoded string*/'
|
{ publicKeyPem: '-----BEGIN RSA PUBLIC KEY-----\n/*base64 pem-encoded string*/'
|
||||||
, privateKeyPem: '/*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: {
|
, privateKeyJwk: {
|
||||||
kty: "RSA"
|
kty: "RSA"
|
||||||
, n: '/*base64 modulus n = pq*/'
|
, n: '/*base64 modulus n = pq*/'
|
||||||
|
@ -47,8 +48,11 @@ RSA.generateKeypair(bitlen, exp, options).then(function (keypair) {
|
||||||
, n: /*base64 modulus n = pq*/
|
, n: /*base64 modulus n = pq*/
|
||||||
, e: /base64 exponent (usually 65537)*/
|
, e: /base64 exponent (usually 65537)*/
|
||||||
}
|
}
|
||||||
|
|
||||||
, _ursa: /*undefined or intermediate ursa object*/
|
, _ursa: /*undefined or intermediate ursa object*/
|
||||||
|
, _ursaPublic: /*undefined or intermediate ursa object*/
|
||||||
, _forge: /*undefined or intermediate forge 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
|
// 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.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)
|
### 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)
|
, 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 cryptoc = module.exports;
|
||||||
var rsaExtra = require('./rsa-extra');
|
var rsaExtra = require('./rsa-extra');
|
||||||
var rsaForge = require('./rsa-forge');
|
var rsaForge = require('./rsa-forge');
|
||||||
var ursac;
|
var rsaUrsa;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ursac = require('./rsa-ursa');
|
rsaUrsa = require('./rsa-ursa');
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
ursac = {};
|
rsaUrsa = {};
|
||||||
// things will run a little slower on keygen, but it'll work on windows
|
// 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)
|
// (but don't try this on raspberry pi - 20+ MINUTES key generation)
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,9 @@ try {
|
||||||
// * ursa
|
// * ursa
|
||||||
// * forge extra (the new one aimed to be less-forgey)
|
// * forge extra (the new one aimed to be less-forgey)
|
||||||
// * forge (fallback)
|
// * forge (fallback)
|
||||||
Object.keys(ursac).forEach(function (key) {
|
Object.keys(rsaUrsa).forEach(function (key) {
|
||||||
if (!cryptoc[key]) {
|
if (!cryptoc[key]) {
|
||||||
cryptoc[key] = ursac[key];
|
cryptoc[key] = rsaUrsa[key];
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(rsaExtra).forEach(function (key) {
|
|
||||||
if (!cryptoc[key]) {
|
|
||||||
cryptoc[key] = rsaExtra[key];
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,3 +34,9 @@ Object.keys(rsaForge).forEach(function (key) {
|
||||||
cryptoc[key] = rsaForge[key];
|
cryptoc[key] = rsaForge[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Object.keys(rsaExtra).forEach(function (key) {
|
||||||
|
if (!cryptoc[key]) {
|
||||||
|
cryptoc[key] = rsaExtra[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -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) {
|
, _privateJwkToComponents: function (jwk) {
|
||||||
var components = [];
|
var components = [];
|
||||||
|
|
||||||
|
// [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
|
||||||
[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
|
[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
|
||||||
components.push(new forgec._base64tobin(jwk[key]));
|
components.push(new forgec._base64tobin(jwk[key]));
|
||||||
});
|
});
|
||||||
|
@ -76,7 +77,7 @@ var forgec = module.exports = {
|
||||||
//
|
//
|
||||||
// Export Public / Private PEMs
|
// Export Public / Private PEMs
|
||||||
//
|
//
|
||||||
, exportPrivateKeyPem: function (keypair) {
|
, exportPrivatePem: function (keypair) {
|
||||||
if (keypair.privateKeyPem) {
|
if (keypair.privateKeyPem) {
|
||||||
return 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");
|
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) {
|
if (keypair.publicKeyPem) {
|
||||||
return keypair.publicKeyPem;
|
return keypair.publicKeyPem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ var ursac = module.exports = {
|
||||||
//
|
//
|
||||||
// Export Public / Private PEMs
|
// Export Public / Private PEMs
|
||||||
//
|
//
|
||||||
, exportPrivateKeyPem: function (keypair) {
|
, exportPrivatePem: function (keypair) {
|
||||||
if (keypair.privateKeyPem) {
|
if (keypair.privateKeyPem) {
|
||||||
return 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");
|
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) {
|
if (keypair.publicKeyPem) {
|
||||||
return keypair.publicKeyPem;
|
return keypair.publicKeyPem;
|
||||||
}
|
}
|
||||||
|
|
15
node.js
15
node.js
|
@ -43,18 +43,11 @@ function create(deps) {
|
||||||
|
|
||||||
options = options || NOBJ;
|
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) {
|
if (false !== options.jwk || options.thumbprint) {
|
||||||
keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keys);
|
keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keys);
|
||||||
if (options.public) {
|
if (options.public) {
|
||||||
keypair.publicKeyJwk = RSA._internal.exportPublicJwk(keys);
|
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;
|
return RSA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ var RSA = require('../').RSA;
|
||||||
console.log('RSA');
|
console.log('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('');
|
||||||
console.log('keys');
|
console.log('keys');
|
||||||
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)
|
, internal: true // preserve internal intermediate formats (_ursa, _forge)
|
||||||
, thumbprint: true // JWK sha256 thumbprint
|
, thumbprint: true // JWK sha256 thumbprint
|
||||||
};
|
};
|
||||||
RSA.generateKeypair(512, 65537, options, function (keys) {
|
RSA.generateKeypair(512, 65537, options, function (err, keys) {
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log('keys');
|
console.log('keys');
|
||||||
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…
Reference in New Issue