| 
									
										
										
										
											2019-01-24 20:18:48 -08:00
										 |  |  | [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js) | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | ========= | 
					
						
							| 
									
										
										
										
											2018-11-20 01:02:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-24 20:18:48 -08:00
										 |  |  | A [Root](https://therootcompany.com) Project. | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js) | 
					
						
							|  |  |  | and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.js) | 
					
						
							| 
									
										
										
										
											2018-11-20 01:02:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-30 13:41:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-23 11:35:31 -07:00
										 |  |  | | ~550 lines of code | 3kb gzipped | 10kb minified | 18kb with comments | | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | RSA tools. Lightweight. Zero Dependencies. Universal compatibility. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * [x] Fast and Easy RSA Key Generation | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | * [x] PEM-to-JWK | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | * [x] JWK-to-PEM | 
					
						
							| 
									
										
										
										
											2019-02-07 00:08:32 -07:00
										 |  |  | * [x] JWK thumbprint | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | * [x] SSH "pub" format | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | * [ ] ECDSA | 
					
						
							|  |  |  |   * **Need EC or ECDSA tools?** Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-30 11:30:12 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | ## 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | Rasha.generate({ format: 'jwk' }).then(function (keypair) { | 
					
						
							|  |  |  |   console.log(keypair.private); | 
					
						
							|  |  |  |   console.log(keypair.public); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **options** | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | * `format` defaults to `'jwk'` | 
					
						
							|  |  |  |   * `'pkcs1'` (traditional) | 
					
						
							| 
									
										
										
										
											2018-11-24 19:47:56 -07:00
										 |  |  |   * `'pkcs8'` <!-- * `'ssh'` --> | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | * `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 | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | **advanced options** | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | These options are provided for debugging and should not be used. | 
					
						
							| 
									
										
										
										
											2018-11-23 12:44:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | * `publicExponent` defaults to 65537 (`0x10001`) | 
					
						
							| 
									
										
										
										
											2018-11-23 12:44:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | ## PEM-to-JWK
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 17:21:54 -07:00
										 |  |  | * [x] PKCS#1 (traditional) | 
					
						
							|  |  |  | * [x] PKCS#8, SPKI/PKIX | 
					
						
							| 
									
										
										
										
											2018-11-24 01:33:12 -07:00
										 |  |  | * [x] 2048-bit, 3072-bit, 4096-bit (and ostensibily all others) | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | * [x] SSH (RFC4716), (RFC 4716/SSH2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var Rasha = require('rasha'); | 
					
						
							|  |  |  | var pem = require('fs') | 
					
						
							|  |  |  |   .readFileSync('./node_modles/rasha/fixtures/privkey-rsa-2048.pkcs1.pem', 'ascii'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rasha.import({ pem: pem }).then(function (jwk) { | 
					
						
							|  |  |  |   console.log(jwk); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   "kty": "RSA", | 
					
						
							|  |  |  |   "n": "m2ttVBxPlWw06ZmGBWVDl...QlEz7UNNj9RGps_50-CNw", | 
					
						
							|  |  |  |   "e": "AQAB", | 
					
						
							|  |  |  |   "d": "Cpfo7Mm9Nu8YMC_xrZ54W...Our1IdDzJ_YfHPt9sHMQQ", | 
					
						
							|  |  |  |   "p": "ynG-t9HwKCN3MWRYFdnFz...E9S4DsGcAarIuOT2TsTCE", | 
					
						
							|  |  |  |   "q": "xIkAjgUzB1zaUzJtW2Zgv...38ahSrBFEVnxjpnPh1Q1c", | 
					
						
							|  |  |  |   "dp": "tzDGjECFOU0ehqtuqhcu...dVGAXJoGOdv5VpaZ7B1QE", | 
					
						
							|  |  |  |   "dq": "kh5dyDk7YCz7sUFbpsmu...aX9PKa12HFlny6K1daL48", | 
					
						
							|  |  |  |   "qi": "AlHWbx1gp6Z9pbw_1hlS...lhmIOgRApS0t9VoXtHhFU" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## JWK-to-PEM
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 17:21:54 -07:00
										 |  |  | * [x] PKCS#1 (traditional) | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | * [x] PKCS#8, SPKI/PKIX | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | * [x] 2048-bit, 4096-bit (and ostensibily all others) | 
					
						
							|  |  |  | * [x] SSH (RFC4716), (RFC 4716/SSH2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var Rasha = require('rasha'); | 
					
						
							| 
									
										
										
										
											2018-11-22 17:21:54 -07:00
										 |  |  | var jwk = require('rasha/fixtures/privkey-rsa-2048.jwk.json'); | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | Rasha.export({ jwk: jwk }).then(function (pem) { | 
					
						
							|  |  |  |   // PEM in PKCS1 (traditional) format | 
					
						
							|  |  |  |   console.log(pem); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | -----BEGIN RSA PRIVATE KEY----- | 
					
						
							|  |  |  | MIIEpAIBAAKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhD | 
					
						
							|  |  |  | NzUJefLukC+xu0LBKylYojT5vTkxaOhxeSYo31syu4WhxbkTBLICOFcCGMob6pSQ | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | 38P8LdAIlb0pqDHxEJ9adWomjuFf.....5cCBahfsiNtNR6WV1/iCSuINYs6uPdA | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | Jlw7hm9m8TAmFWWyfL0s7wiRvAYkQvpxetorTwHJVLabBDJ+WBOAY2enOLHIRQv+ | 
					
						
							|  |  |  | atAvHrLXjkUdzF96o0icyF6n7QzGfUPmeWGYg6BEClLS31Whe0eEVQ== | 
					
						
							|  |  |  | -----END RSA PRIVATE KEY----- | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Advanced Options
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `format: 'pkcs8'`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The default output format `pkcs1` (RSA-specific format) is used for private keys. | 
					
						
							|  |  |  | Use `format: 'pkcs8'` to output in PKCS#8 format instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | Rasha.export({ jwk: jwk, format: 'pkcs8' }).then(function (pem) { | 
					
						
							|  |  |  |   // PEM in PKCS#8 format | 
					
						
							|  |  |  |   console.log(pem); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | -----BEGIN PRIVATE KEY----- | 
					
						
							|  |  |  | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCba21UHE+VbDTp | 
					
						
							|  |  |  | mYYFZUOV+OQ8AngOCdjROsPC0KiEfMvEaEM3NQl58u6QL7G7QsErKViiNPm9OTFo | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | 6HF5JijfWzK7haHFuRMEsgI4VwIY.....LorV1ovjwKBgAJR1m8dYKemfaW8P9YZ | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | Uux7lwIFqF+yI201HpZXX+IJK4g1izq490AmXDuGb2bxMCYVZbJ8vSzvCJG8BiRC | 
					
						
							|  |  |  | +nF62itPAclUtpsEMn5YE4BjZ6c4schFC/5q0C8esteORR3MX3qjSJzIXqftDMZ9 | 
					
						
							|  |  |  | Q+Z5YZiDoEQKUtLfVaF7R4RV | 
					
						
							|  |  |  | -----END PRIVATE KEY----- | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `format: 'ssh'`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Although SSH uses PKCS#1 for private keys, it uses ts own special non-ASN1 format | 
					
						
							|  |  |  | (affectionately known as rfc4716) for public keys. I got curious and then decided | 
					
						
							|  |  |  | to add this format as well. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To get the same format as you | 
					
						
							|  |  |  | would get with `ssh-keygen`, pass `ssh` as the format option: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | Rasha.export({ jwk: jwk, format: 'ssh' }).then(function (pub) { | 
					
						
							|  |  |  |   // Special SSH2 Public Key format (RFC 4716) | 
					
						
							|  |  |  |   console.log(pub); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCba21UHE.....Q02P1Eamz/nT4I3 rsa@localhost | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `public: 'true'`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If a private key is used as input, a private key will be output. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you'd like to output a public key instead you can pass `public: true`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | or `format: 'spki'`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | Rasha.export({ jwk: jwk, public: true }).then(function (pem) { | 
					
						
							|  |  |  |   // PEM in SPKI/PKIX format | 
					
						
							|  |  |  |   console.log(pem); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | -----BEGIN PUBLIC KEY----- | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | MIIBCgKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhDNzUJ | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | efLukC+xu0LBKylYojT5vTkxaOhx.....TmzCh2ikrwTMja7mUdBJf2bK3By5AB0 | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | Qi49OykUCfNZeQlEz7UNNj9RGps/50+CNwIDAQAB | 
					
						
							| 
									
										
										
										
											2018-11-22 23:41:39 -07:00
										 |  |  | -----END PUBLIC KEY----- | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 00:08:32 -07:00
										 |  |  | ## JWK Thumbprint
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | Rasha.thumbprint({ jwk: jwk }).then(function (thumbprint) { | 
					
						
							|  |  |  |   console.log(thumbprint); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | Testing | 
					
						
							|  |  |  | ------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 23:45:53 -07:00
										 |  |  | All cases are tested in `test.sh`. | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-23 23:36:57 -07:00
										 |  |  | You can compare these keys to the ones that you get from OpenSSL, OpenSSH/ssh-keygen, and WebCrypto: | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | # Generate 2048-bit RSA Keypair
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | openssl genrsa -out privkey-rsa-2048.pkcs1.pem 2048 | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Convert PKCS1 (traditional) RSA Keypair to PKCS8 format
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | openssl rsa -in privkey-rsa-2048.pkcs1.pem -pubout -out pub-rsa-2048.spki.pem | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Export Public-only RSA Key in PKCS1 (traditional) format
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | openssl pkcs8 -topk8 -nocrypt -in privkey-rsa-2048.pkcs1.pem -out privkey-rsa-2048.pkcs8.pem | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Convert PKCS1 (traditional) RSA Public Key to SPKI/PKIX format
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | openssl rsa -in pub-rsa-2048.spki.pem -pubin -RSAPublicKey_out -out pub-rsa-2048.pkcs1.pem | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Convert RSA public key to SSH format
 | 
					
						
							| 
									
										
										
										
											2018-11-21 01:19:57 -07:00
										 |  |  | ssh-keygen -f ./pub-rsa-2048.spki.pem -i -mPKCS8 > ./pub-rsa-2048.ssh.pub | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | Goals of this project | 
					
						
							|  |  |  | ----- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Focused support for 2048-bit and 4096-bit RSA keypairs (although any size is technically supported) | 
					
						
							| 
									
										
										
										
											2018-11-23 11:35:31 -07:00
										 |  |  | * Zero Dependencies | 
					
						
							|  |  |  | * VanillaJS | 
					
						
							|  |  |  | * Quality Code: Good comments and tests | 
					
						
							|  |  |  | * Convert both ways: PEM-to-JWK and JWK-to-PEM (also supports SSH pub files) | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | * Browser support as well (TODO) | 
					
						
							|  |  |  | * OpenSSL, ssh-keygen, and WebCrypto compatibility | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Legal | 
					
						
							|  |  |  | ----- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-23 23:52:24 -07:00
										 |  |  | [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js) | | 
					
						
							|  |  |  | MPL-2.0 | | 
					
						
							| 
									
										
										
										
											2018-11-22 04:05:00 -07:00
										 |  |  | [Terms of Use](https://therootcompany.com/legal/#terms) | | 
					
						
							|  |  |  | [Privacy Policy](https://therootcompany.com/legal/#privacy) |