Browse Source

generate RSA keys with node 10.12+

tags/v1.1.0
AJ ONeal 6 months ago
parent
commit
6cd0c28b86
5 changed files with 131 additions and 9 deletions
  1. 31
    7
      README.md
  2. 16
    0
      bin/rasha.js
  3. 71
    0
      lib/rasha.js
  4. 1
    1
      package.json
  5. 12
    1
      test.sh

+ 31
- 7
README.md View File

@@ -5,27 +5,51 @@ Sponsored by [Root](https://therootcompany.com).
5 5
 Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js)
6 6
 and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.js)
7 7
 
8
-RSA tools. Lightweight. Zero Dependencies. Universal compatibility.
9
-
10 8
 | ~550 lines of code | 3kb gzipped | 10kb minified | 18kb with comments |
11 9
 
10
+RSA tools. Lightweight. Zero Dependencies. Universal compatibility.
11
+
12
+* [x] Fast and Easy RSA Key Generation
12 13
 * [x] PEM-to-JWK
13 14
 * [x] JWK-to-PEM
14 15
 * [x] SSH "pub" format
16
+* [ ] ECDSA
17
+  * **Need EC or ECDSA tools?** Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
18
+
19
+## Generate RSA Key
20
+
21
+Achieves the *fastest possible key generation* using node's native RSA bindings to OpenSSL,
22
+then converts to JWK for ease-of-use.
15 23
 
16
-This project is fully functional and tested (and the code is pretty clean).
24
+```
25
+Rasha.generate({ format: 'jwk' }).then(function (keypair) {
26
+  console.log(keypair.private);
27
+  console.log(keypair.public);
28
+});
29
+```
17 30
 
18
-It is considered to be complete, but if you find a bug please open an issue.
31
+**options**
19 32
 
20
-## Looking for ECDSA as well?
33
+* `format` defaults to `'jwk'`
34
+  * `'pkcs1'` (traditional)
35
+  * `'pkcs8'`
36
+* `modulusLength` defaults to 2048 (must not be lower)
37
+  * generally you shouldn't pick a larger key size - they're slow
38
+  * **2048** is more than sufficient
39
+  * 3072 is way, way overkill and takes a few seconds to generate
40
+  * 4096 can take about a minute to generate and is just plain wasteful
21 41
 
22
-Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
42
+**advanced options**
43
+
44
+These options are provided for debugging and should not be used.
45
+
46
+* `publicExponent` defaults to 65537 (`0x10001`)
23 47
 
24 48
 ## PEM-to-JWK
25 49
 
26 50
 * [x] PKCS#1 (traditional)
27 51
 * [x] PKCS#8, SPKI/PKIX
28
-* [x] 2048-bit, 4096-bit (and ostensibily all others)
52
+* [x] 2048-bit, 3072-bit, 4096-bit (and ostensibily all others)
29 53
 * [x] SSH (RFC4716), (RFC 4716/SSH2)
30 54
 
31 55
 ```js

+ 16
- 0
bin/rasha.js View File

@@ -9,6 +9,22 @@ var ASN1 = require('../lib/asn1.js');
9 9
 var infile = process.argv[2];
10 10
 var format = process.argv[3];
11 11
 
12
+if (!infile) {
13
+  infile = 'jwk';
14
+}
15
+
16
+if (-1 !== [ 'jwk', 'pem', 'json', 'der', 'pkcs1', 'pkcs8', 'spki' ].indexOf(infile)) {
17
+  console.log("Generating new key...");
18
+  Rasha.generate({
19
+    format: infile
20
+  , modulusLength: parseInt(format, 10) || 2048
21
+  , encoding: parseInt(format, 10) ? null : format
22
+  }).then(function (key) {
23
+    console.log(key.private);
24
+    console.log(key.public);
25
+  });
26
+  return;
27
+}
12 28
 var key = fs.readFileSync(infile, 'ascii');
13 29
 
14 30
 try {

+ 71
- 0
lib/rasha.js View File

@@ -7,6 +7,77 @@ var x509 = require('./x509.js');
7 7
 var ASN1 = require('./asn1.js');
8 8
 
9 9
 /*global Promise*/
10
+RSA.generate = function (opts) {
11
+  return Promise.resolve().then(function () {
12
+    var typ = 'rsa';
13
+    var format = opts.format;
14
+    var encoding = opts.encoding;
15
+    var priv;
16
+    var pub;
17
+
18
+    if (!format) {
19
+      format = 'jwk';
20
+    }
21
+    if ('spki' === format || 'pkcs8' === format) {
22
+      format = 'pkcs8';
23
+      pub = 'spki';
24
+    }
25
+
26
+    if ('pem' === format) {
27
+      format = 'pkcs1';
28
+      encoding = 'pem';
29
+    } else if ('der' === format) {
30
+      format = 'pkcs1';
31
+      encoding = 'der';
32
+    }
33
+
34
+    if ('jwk' === format || 'json' === format) {
35
+      format = 'jwk';
36
+      encoding = 'json';
37
+    } else {
38
+      priv = format;
39
+      pub = pub || format;
40
+    }
41
+
42
+    if (!encoding) {
43
+      encoding = 'pem';
44
+    }
45
+
46
+    if (priv) {
47
+      priv = { type: priv, format: encoding };
48
+      pub = { type: pub, format: encoding };
49
+    } else {
50
+      // jwk
51
+      priv = { type: 'pkcs1', format: 'pem' };
52
+      pub = { type: 'pkcs1', format: 'pem' };
53
+    }
54
+
55
+    return new Promise(function (resolve, reject) {
56
+      return require('crypto').generateKeyPair(typ, {
57
+        modulusLength: opts.modulusLength || 2048
58
+      , publicExponent: opts.publicExponent || 0x10001
59
+      , privateKeyEncoding: priv
60
+      , publicKeyEncoding: pub
61
+      }, function (err, pubkey, privkey) {
62
+        if (err) { reject(err); }
63
+        resolve({
64
+          private: privkey
65
+        , public: pubkey
66
+        });
67
+      });
68
+    }).then(function (keypair) {
69
+      if ('jwk' !== format) {
70
+        return keypair;
71
+      }
72
+
73
+      return {
74
+        private: RSA.importSync({ pem: keypair.private, format: priv.format })
75
+      , public: RSA.importSync({ pem: keypair.public, format: pub.format, public: true })
76
+      };
77
+    });
78
+  });
79
+};
80
+
10 81
 RSA.importSync = function (opts) {
11 82
   if (!opts || !opts.pem || 'string' !== typeof opts.pem) {
12 83
     throw new Error("must pass { pem: pem } as a string");

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "rasha",
3
-  "version": "1.0.5",
3
+  "version": "1.1.0",
4 4
   "description": "💯 PEM-to-JWK and JWK-to-PEM for RSA keys in a lightweight, zero-dependency library focused on perfect universal compatibility.",
5 5
   "homepage": "https://git.coolaj86.com/coolaj86/rasha.js",
6 6
   "main": "index.js",

+ 12
- 1
test.sh View File

@@ -122,6 +122,18 @@ pemtojwk ""
122 122
 jwktopem ""
123 123
 
124 124
 echo ""
125
+echo "testing node key generation"
126
+node bin/rasha.js > /dev/null
127
+node bin/rasha.js jwk > /dev/null
128
+node bin/rasha.js json 2048 > /dev/null
129
+node bin/rasha.js der > /dev/null
130
+node bin/rasha.js pkcs8 der > /dev/null
131
+node bin/rasha.js pem > /dev/null
132
+node bin/rasha.js pkcs1 pem > /dev/null
133
+node bin/rasha.js spki > /dev/null
134
+echo "PASS"
135
+
136
+echo ""
125 137
 echo ""
126 138
 echo "Re-running tests with random keys of varying sizes"
127 139
 echo ""
@@ -140,7 +152,6 @@ echo ""
140 152
 echo "Note:"
141 153
 echo "Keys larger than 2048 have been tested and work, but are omitted from automated tests to save time."
142 154
 
143
-
144 155
 rm fixtures/*.1.*
145 156
 
146 157
 echo ""

Loading…
Cancel
Save