215 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| [RSA-CSR.js](https://git.coolaj86.com/coolaj86/rsa-csr.js)
 | |
| ==========
 | |
| 
 | |
| 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-express.js)
 | |
| 
 | |
| A focused, **zero-dependency** library that can do exactly one thing really, really well:
 | |
|   * Generate a Certificate Signing Requests (CSR), and sign it!
 | |
| 
 | |
| | < 300 lines of code | 1.7k gzipped | 4.7k minified | 8.5k with comments |
 | |
| 
 | |
| Need JWK-to-PEM? Try [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js)
 | |
| 
 | |
| Need to generate an EC CSR? Try [ECSDA-CSR.js](https://git.coolaj86.com/coolaj86/ecdsa-csr.js)
 | |
| 
 | |
| Features
 | |
| ========
 | |
| 
 | |
| * [x] Universal CSR support (RSA signing) that Just Works™
 | |
|   * Common Name (CN) Subject
 | |
|   * Subject Alternative Names (SANs / altnames)
 | |
|   * 2048, 3072, and 4096 bit JWK RSA
 | |
|   * RSASSA PKCS1 v1.5
 | |
| * [x] Zero Dependencies
 | |
|   * (no ASN1.js, PKI.js, forge, jrsasign - not even elliptic.js!)
 | |
| * [x] Quality
 | |
|   * Focused
 | |
|   * Lightweight
 | |
|   * Well-Commented, Well-Documented
 | |
|   * Secure
 | |
| * [x] Vanilla Node.js
 | |
|   * no school like the old school
 | |
|   * easy to read and understand
 | |
| 
 | |
| Usage
 | |
| -----
 | |
| 
 | |
| Given an array of domains it uses the first for the  Common Name (CN),
 | |
| also known as Subject, and all of them as the Subject Alternative Names (SANs or altnames).
 | |
| 
 | |
| ```js
 | |
| 'use strict';
 | |
| 
 | |
| var rsacsr = require('rsa-csr');
 | |
| var key = {
 | |
|   "kty": "RSA",
 | |
|   "n": "m2tt...-CNw",
 | |
|   "e": "AQAB",
 | |
|   "d": "Cpfo...HMQQ",
 | |
|   "p": "ynG-...sTCE",
 | |
|   "q": "xIkA...1Q1c",
 | |
|   "dp": "tzDG...B1QE",
 | |
|   "dq": "kh5d...aL48",
 | |
|   "qi": "AlHW...HhFU"
 | |
| };
 | |
| var domains = [ 'example.com', 'www.example.com' ];
 | |
| 
 | |
| return rsacsr({ key: key, domains: domains }).then(function (csr) {
 | |
|   console.log('CSR PEM:');
 | |
|   console.log(csr);
 | |
| });
 | |
| ```
 | |
| 
 | |
| The output will look something like this (but much longer):
 | |
| 
 | |
| ```
 | |
| -----BEGIN CERTIFICATE REQUEST-----
 | |
| MIIClTCCAX0CAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
 | |
| DQEBAQUAA4IBDwAwggEKAoIBAQCba21UHE+VbDTpmYYFZUOV+OQ8AngOCdjROsPC
 | |
| 0KiEfMvEaEM3NQl58u6QL7G7QsEr.....3pIpUUkx5WbwJY6xDrCyFKG8ktpnee6
 | |
| WjpTOBnpgHUI1/5ydnf0v29L9N+ALIJGKQxhub3iqB6EhCl93iiQtf4e7M/lzX7l
 | |
| c1xqsSwVZ3RQVY9bRP9NdGuW4hVvscy5ypqRtXPXQpxMnYwfi9qW5Uo=
 | |
| -----END CERTIFICATE REQUEST-----
 | |
| ```
 | |
| 
 | |
| #### PEM-to-JWK
 | |
| 
 | |
| If you need to convert a PEM to JWK first, do so:
 | |
| 
 | |
| ```js
 | |
| var Rasha = require('rasha');
 | |
| 
 | |
| Rasha.import({ pem: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAI..." }).then(function (jwk) {
 | |
|   console.log(jwk);
 | |
| })
 | |
| ```
 | |
| 
 | |
| #### CLI
 | |
| 
 | |
| You're probably better off using OpenSSL for most commandline tasks,
 | |
| but the `rsa-csr` and `rasha` CLIs are useful for testing and debugging.
 | |
| 
 | |
| ```bash
 | |
| npm install -g rsa-csr
 | |
| npm install -g rasha
 | |
| 
 | |
| rasha ./privkey.pem > ./privkey.jwk.json
 | |
| rsa-csr ./privkey.jwk.json example.com,www.example.com > csr.pem
 | |
| ```
 | |
| 
 | |
| ### Options
 | |
| 
 | |
| * `key` should be a JWK
 | |
|   * Need PEM support? Use [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js).
 | |
|   * (supports PEM, DER, PKCS#1 and PKCS#8)
 | |
| * `domains` must be a list of strings representing domain names
 | |
|   * correctly handles utf-8
 | |
|   * you may also use punycoded, if needed
 | |
| * `subject` will be `domains[0]` by default
 | |
|   * you shouldn't use this unless you need to
 | |
|   * you may need to if you need utf-8 for domains, but punycode for the subject
 | |
| 
 | |
| ### Testing
 | |
| 
 | |
| You can double check that the CSR you get out is actually valid:
 | |
| 
 | |
| ```bash
 | |
| # Generate a key, if needed
 | |
| openssl genrsa -out ./privkey-rsa.pkcs1.pem $keysize
 | |
| 
 | |
| # Convert to JWK
 | |
| rasha ./privkey-rsa.pkcs1.pem > ./privkey-rsa.jwk.json
 | |
| 
 | |
| # Create a CSR with your domains
 | |
| npx rsa-csr ./privkey-rsa.jwk.json example.com,www.example.com > csr.pem
 | |
| 
 | |
| # Verify
 | |
| openssl req -text -noout -verify -in csr.pem
 | |
| ```
 | |
| 
 | |
| New to Crypto?
 | |
| --------------
 | |
| 
 | |
| Just a heads up in case you have no idea what you're doing:
 | |
| 
 | |
| First of all, [don't panic](https://coolaj86.com/articles/dont-panic.html).
 | |
| 
 | |
| Next:
 | |
| 
 | |
| * RSA stands for... well, that doesn't matter, actually.
 | |
| * DSA stands for _Digital Signing Algorithm_.
 | |
| * RSA a separate standard from EC/ECDSA, but both are *asymmetric*
 | |
| * Private keys are actually keypairs (they contain the public key)
 | |
| 
 | |
| In many cases the terms get used (and misused) interchangably,
 | |
| which can be confusing. You'll survive, I promise.
 | |
| 
 | |
| * PEM is just a Base64-encoded DER (think JSON as hex or base64)
 | |
| * DER is an binary _object notation_ for ASN.1 (think actual stringified JSON or XML)
 | |
| * ASN.1 is _object notation_ standard (think JSON, the standard)
 | |
| * X.509 is a suite of schemas (think XLST or json-schema.org)
 | |
| * PKCS#8, PKIK, SPKI are all X.509 schemas (think defining `firstName` vs `first_name` vs `firstname`)
 | |
| 
 | |
| Now forget about all that and just know this:
 | |
| 
 | |
| **This library solves your problem if** you need RSA _something-or-other_ and CSR _something-or-other_
 | |
| in order to deal with SSL certificates in an internal organization.
 | |
| 
 | |
| If that's not what you're doing, you may want HTTPS and SSL through
 | |
| [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock-express.js),
 | |
| or you may be looking for something else entirely.
 | |
| 
 | |
| Goals vs Non-Goals
 | |
| -----
 | |
| 
 | |
| This was built for use by [ACME.js](https://git.coolaj86.com/coolaj86/acme.js)
 | |
| and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock-express.js).
 | |
| 
 | |
| Rather than trying to make a generic implementation that works with everything under the sun,
 | |
| this library is intentionally focused on around the use case of generating certificates for
 | |
| ACME services (such as Let's Encrypt).
 | |
| 
 | |
| That said, [please tell me](https://git.coolaj86.com/coolaj86/rsa-csr.js/issues/new) if it doesn't
 | |
| do what you need, it may make sense to add it (or otherwise, perhaps to help you create a fork).
 | |
| 
 | |
| The primary goal of this project is for this code to do exactly (and all of)
 | |
| what it needs to do - No more, no less.
 | |
| 
 | |
| * Support RSA JWKs
 | |
|   * 2048-bit
 | |
|   * 3072-bit
 | |
|   * 4096-bit
 | |
| * Support PEM and DER via Rasha.js
 | |
|   * PKCS#1 (traditional)
 | |
|   * PKCS#8
 | |
|   * RSASSA-PKCS1-v1_5
 | |
| * Vanilla node.js (ECMAScript 5.1)
 | |
|   * No babel
 | |
|   * No dependencies
 | |
| 
 | |
| However, there are a few areas where I'd be willing to stretch:
 | |
| 
 | |
| * Type definition files for altscript languages
 | |
| 
 | |
| It is not a goal of this project to support any RSA profiles
 | |
| except those that are universally supported by browsers and
 | |
| are sufficiently secure (overkill is overkill).
 | |
| 
 | |
| > A little copying is better than a little dependency. - [Go Proverbs](https://go-proverbs.github.io) by Rob Pike
 | |
| 
 | |
| This code is considered small and focused enough that,
 | |
| rather than making it a dependency in other small projects,
 | |
| I personally just copy over the code.
 | |
| 
 | |
| Hence, all of these projects are MPL-2.0 licensed.
 | |
| 
 | |
| Legal
 | |
| -----
 | |
| 
 | |
| [RSA-CSR.js](https://git.coolaj86.com/coolaj86/rsa-csr.js) |
 | |
| MPL-2.0 |
 | |
| [Terms of Use](https://therootcompany.com/legal/#terms) |
 | |
| [Privacy Policy](https://therootcompany.com/legal/#privacy)
 |