generate RSA keys with node 10.12+
This commit is contained in:
parent
40bb9a0fdd
commit
6cd0c28b86
5 changed files with 131 additions and 9 deletions
38
README.md
38
README.md
|
@ -5,27 +5,51 @@ Sponsored by [Root](https://therootcompany.com).
|
|||
Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js)
|
||||
and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.js)
|
||||
|
||||
RSA tools. Lightweight. Zero Dependencies. Universal compatibility.
|
||||
|
||||
| ~550 lines of code | 3kb gzipped | 10kb minified | 18kb with comments |
|
||||
|
||||
RSA tools. Lightweight. Zero Dependencies. Universal compatibility.
|
||||
|
||||
* [x] Fast and Easy RSA Key Generation
|
||||
* [x] PEM-to-JWK
|
||||
* [x] JWK-to-PEM
|
||||
* [x] SSH "pub" format
|
||||
* [ ] ECDSA
|
||||
* **Need EC or ECDSA tools?** Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
|
||||
|
||||
This project is fully functional and tested (and the code is pretty clean).
|
||||
## Generate RSA Key
|
||||
|
||||
It is considered to be complete, but if you find a bug please open an issue.
|
||||
Achieves the *fastest possible key generation* using node's native RSA bindings to OpenSSL,
|
||||
then converts to JWK for ease-of-use.
|
||||
|
||||
## Looking for ECDSA as well?
|
||||
```
|
||||
Rasha.generate({ format: 'jwk' }).then(function (keypair) {
|
||||
console.log(keypair.private);
|
||||
console.log(keypair.public);
|
||||
});
|
||||
```
|
||||
|
||||
Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
|
||||
**options**
|
||||
|
||||
* `format` defaults to `'jwk'`
|
||||
* `'pkcs1'` (traditional)
|
||||
* `'pkcs8'`
|
||||
* `modulusLength` defaults to 2048 (must not be lower)
|
||||
* generally you shouldn't pick a larger key size - they're slow
|
||||
* **2048** is more than sufficient
|
||||
* 3072 is way, way overkill and takes a few seconds to generate
|
||||
* 4096 can take about a minute to generate and is just plain wasteful
|
||||
|
||||
**advanced options**
|
||||
|
||||
These options are provided for debugging and should not be used.
|
||||
|
||||
* `publicExponent` defaults to 65537 (`0x10001`)
|
||||
|
||||
## PEM-to-JWK
|
||||
|
||||
* [x] PKCS#1 (traditional)
|
||||
* [x] PKCS#8, SPKI/PKIX
|
||||
* [x] 2048-bit, 4096-bit (and ostensibily all others)
|
||||
* [x] 2048-bit, 3072-bit, 4096-bit (and ostensibily all others)
|
||||
* [x] SSH (RFC4716), (RFC 4716/SSH2)
|
||||
|
||||
```js
|
||||
|
|
16
bin/rasha.js
16
bin/rasha.js
|
@ -9,6 +9,22 @@ var ASN1 = require('../lib/asn1.js');
|
|||
var infile = process.argv[2];
|
||||
var format = process.argv[3];
|
||||
|
||||
if (!infile) {
|
||||
infile = 'jwk';
|
||||
}
|
||||
|
||||
if (-1 !== [ 'jwk', 'pem', 'json', 'der', 'pkcs1', 'pkcs8', 'spki' ].indexOf(infile)) {
|
||||
console.log("Generating new key...");
|
||||
Rasha.generate({
|
||||
format: infile
|
||||
, modulusLength: parseInt(format, 10) || 2048
|
||||
, encoding: parseInt(format, 10) ? null : format
|
||||
}).then(function (key) {
|
||||
console.log(key.private);
|
||||
console.log(key.public);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var key = fs.readFileSync(infile, 'ascii');
|
||||
|
||||
try {
|
||||
|
|
71
lib/rasha.js
71
lib/rasha.js
|
@ -7,6 +7,77 @@ var x509 = require('./x509.js');
|
|||
var ASN1 = require('./asn1.js');
|
||||
|
||||
/*global Promise*/
|
||||
RSA.generate = function (opts) {
|
||||
return Promise.resolve().then(function () {
|
||||
var typ = 'rsa';
|
||||
var format = opts.format;
|
||||
var encoding = opts.encoding;
|
||||
var priv;
|
||||
var pub;
|
||||
|
||||
if (!format) {
|
||||
format = 'jwk';
|
||||
}
|
||||
if ('spki' === format || 'pkcs8' === format) {
|
||||
format = 'pkcs8';
|
||||
pub = 'spki';
|
||||
}
|
||||
|
||||
if ('pem' === format) {
|
||||
format = 'pkcs1';
|
||||
encoding = 'pem';
|
||||
} else if ('der' === format) {
|
||||
format = 'pkcs1';
|
||||
encoding = 'der';
|
||||
}
|
||||
|
||||
if ('jwk' === format || 'json' === format) {
|
||||
format = 'jwk';
|
||||
encoding = 'json';
|
||||
} else {
|
||||
priv = format;
|
||||
pub = pub || format;
|
||||
}
|
||||
|
||||
if (!encoding) {
|
||||
encoding = 'pem';
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
priv = { type: priv, format: encoding };
|
||||
pub = { type: pub, format: encoding };
|
||||
} else {
|
||||
// jwk
|
||||
priv = { type: 'pkcs1', format: 'pem' };
|
||||
pub = { type: 'pkcs1', format: 'pem' };
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
return require('crypto').generateKeyPair(typ, {
|
||||
modulusLength: opts.modulusLength || 2048
|
||||
, publicExponent: opts.publicExponent || 0x10001
|
||||
, privateKeyEncoding: priv
|
||||
, publicKeyEncoding: pub
|
||||
}, function (err, pubkey, privkey) {
|
||||
if (err) { reject(err); }
|
||||
resolve({
|
||||
private: privkey
|
||||
, public: pubkey
|
||||
});
|
||||
});
|
||||
}).then(function (keypair) {
|
||||
if ('jwk' !== format) {
|
||||
return keypair;
|
||||
}
|
||||
|
||||
return {
|
||||
private: RSA.importSync({ pem: keypair.private, format: priv.format })
|
||||
, public: RSA.importSync({ pem: keypair.public, format: pub.format, public: true })
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
RSA.importSync = function (opts) {
|
||||
if (!opts || !opts.pem || 'string' !== typeof opts.pem) {
|
||||
throw new Error("must pass { pem: pem } as a string");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rasha",
|
||||
"version": "1.0.5",
|
||||
"version": "1.1.0",
|
||||
"description": "💯 PEM-to-JWK and JWK-to-PEM for RSA keys in a lightweight, zero-dependency library focused on perfect universal compatibility.",
|
||||
"homepage": "https://git.coolaj86.com/coolaj86/rasha.js",
|
||||
"main": "index.js",
|
||||
|
|
13
test.sh
13
test.sh
|
@ -121,6 +121,18 @@ rndkey() {
|
|||
pemtojwk ""
|
||||
jwktopem ""
|
||||
|
||||
echo ""
|
||||
echo "testing node key generation"
|
||||
node bin/rasha.js > /dev/null
|
||||
node bin/rasha.js jwk > /dev/null
|
||||
node bin/rasha.js json 2048 > /dev/null
|
||||
node bin/rasha.js der > /dev/null
|
||||
node bin/rasha.js pkcs8 der > /dev/null
|
||||
node bin/rasha.js pem > /dev/null
|
||||
node bin/rasha.js pkcs1 pem > /dev/null
|
||||
node bin/rasha.js spki > /dev/null
|
||||
echo "PASS"
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Re-running tests with random keys of varying sizes"
|
||||
|
@ -140,7 +152,6 @@ echo ""
|
|||
echo "Note:"
|
||||
echo "Keys larger than 2048 have been tested and work, but are omitted from automated tests to save time."
|
||||
|
||||
|
||||
rm fixtures/*.1.*
|
||||
|
||||
echo ""
|
||||
|
|
Loading…
Reference in a new issue