Browse Source

generate RSA keys with node 10.12+

master v1.1.0
AJ ONeal 6 years ago
parent
commit
6cd0c28b86
  1. 38
      README.md
  2. 16
      bin/rasha.js
  3. 71
      lib/rasha.js
  4. 2
      package.json
  5. 13
      test.sh

38
README.md

@ -5,27 +5,51 @@ Sponsored by [Root](https://therootcompany.com).
Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js) Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js)
and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.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 | | ~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] PEM-to-JWK
* [x] JWK-to-PEM * [x] JWK-to-PEM
* [x] SSH "pub" format * [x] SSH "pub" format
* [ ] ECDSA
* **Need EC or ECDSA tools?** Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
## Generate RSA Key
Achieves the *fastest possible key generation* using node's native RSA bindings to OpenSSL,
then converts to JWK for ease-of-use.
This project is fully functional and tested (and the code is pretty clean). ```
Rasha.generate({ format: 'jwk' }).then(function (keypair) {
console.log(keypair.private);
console.log(keypair.public);
});
```
It is considered to be complete, but if you find a bug please open an issue. **options**
## Looking for ECDSA as well? * `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
Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js) **advanced options**
These options are provided for debugging and should not be used.
* `publicExponent` defaults to 65537 (`0x10001`)
## PEM-to-JWK ## PEM-to-JWK
* [x] PKCS#1 (traditional) * [x] PKCS#1 (traditional)
* [x] PKCS#8, SPKI/PKIX * [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) * [x] SSH (RFC4716), (RFC 4716/SSH2)
```js ```js

16
bin/rasha.js

@ -9,6 +9,22 @@ var ASN1 = require('../lib/asn1.js');
var infile = process.argv[2]; var infile = process.argv[2];
var format = process.argv[3]; 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'); var key = fs.readFileSync(infile, 'ascii');
try { try {

71
lib/rasha.js

@ -7,6 +7,77 @@ var x509 = require('./x509.js');
var ASN1 = require('./asn1.js'); var ASN1 = require('./asn1.js');
/*global Promise*/ /*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) { RSA.importSync = function (opts) {
if (!opts || !opts.pem || 'string' !== typeof opts.pem) { if (!opts || !opts.pem || 'string' !== typeof opts.pem) {
throw new Error("must pass { pem: pem } as a string"); throw new Error("must pass { pem: pem } as a string");

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "rasha", "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.", "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", "homepage": "https://git.coolaj86.com/coolaj86/rasha.js",
"main": "index.js", "main": "index.js",

13
test.sh

@ -121,6 +121,18 @@ rndkey() {
pemtojwk "" pemtojwk ""
jwktopem "" 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 "" echo ""
echo "Re-running tests with random keys of varying sizes" echo "Re-running tests with random keys of varying sizes"
@ -140,7 +152,6 @@ echo ""
echo "Note:" echo "Note:"
echo "Keys larger than 2048 have been tested and work, but are omitted from automated tests to save time." echo "Keys larger than 2048 have been tested and work, but are omitted from automated tests to save time."
rm fixtures/*.1.* rm fixtures/*.1.*
echo "" echo ""

Loading…
Cancel
Save