171 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | ECDSA-CSR.js | ||
|  | ========= | ||
|  | 
 | ||
|  | Sponsored by [Root](https://therootcompany.com) | ||
|  | 
 | ||
|  | A focused, **zero-dependency** library that can do exactly one thing really, really well: | ||
|  |   * Generate a Certificate Signing Requests (CSR), and sign it! | ||
|  | 
 | ||
|  | Features | ||
|  | ======== | ||
|  | 
 | ||
|  | * [x] Universal ECDSA and CSR support that Just Works™ | ||
|  |   * NIST P-256 (also known as prime256v1 or secp256r1) | ||
|  |   * PEM, DER, ASN.1, PKCS8 (Private Key), PKIX/SPKI (Public Key) | ||
|  |   * Common Name (CN) Subject | ||
|  |   * Subject Alternative Names (SANs / altnames) | ||
|  | * [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 edsacsr = require('ecdsa-csr'); | ||
|  | var domains = [ 'example.com', 'www.example.com', 'api.example.com' ]; | ||
|  | 
 | ||
|  | return ecdsacsr({ key: key, domains: domains }).then(function (csr) { | ||
|  |   console.log('CSR PEM:', csr); | ||
|  | }); | ||
|  | ``` | ||
|  | 
 | ||
|  | ### Options
 | ||
|  | 
 | ||
|  | * `key` must be a PEM or DER | ||
|  |   * PEM may be a plain string or a Buffer* | ||
|  |   * DER must be a Buffer* | ||
|  | * `domains` must be a list of strings representing domain names | ||
|  |   * must be plain oldl utf8, not punycode | ||
|  | 
 | ||
|  | * "Buffer" can be a node Buffer, a JavaScript Uint8Array, | ||
|  | or a JavaScript Array which contains only numbers between 0 and 255. | ||
|  | 
 | ||
|  | Other useful options: | ||
|  | 
 | ||
|  | * `der: true` output a der instead of a PEM | ||
|  | * `format: string|Array|Buffer|Uint8Array` output the PEM or DER in the desired format. | ||
|  | 
 | ||
|  | ### Verifying
 | ||
|  | 
 | ||
|  | You can double check that the CSR you get out is actually valid: | ||
|  | 
 | ||
|  | ```bash | ||
|  | # Generate a key
 | ||
|  | openssl ecparam -genkey -name prime256v1 -noout -out ./privkey-ec-p256.pem | ||
|  | 
 | ||
|  | # Create a CSR
 | ||
|  | npx ecdsa-csr ./privkey-ec-p256.pem example.com,www.example.com > csr.pem | ||
|  | 
 | ||
|  | # Verify
 | ||
|  | openssl req -text -noout -verify -in csr.pem | ||
|  | ``` | ||
|  | 
 | ||
|  | Known Issues | ||
|  | ------------ | ||
|  | 
 | ||
|  | I've learned to be careful about talking about the future, | ||
|  | however, I literally just published this tonight (2018-11-17) | ||
|  | and there are a few things I plan to address but haven't yet: | ||
|  | 
 | ||
|  | * JWK not yet supported | ||
|  | * non-ascii domains, such as 例.中国 not yet supported | ||
|  | * total domains length over 127 characters not yet supported | ||
|  | 
 | ||
|  | 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: | ||
|  | 
 | ||
|  | * EC stands for _Elliptic Curve_. | ||
|  | * DSA stands for _Digital Signing Algorithm_. | ||
|  | * EC, ECDSA, and ECDH all belong to the same suite of tools. | ||
|  | * Private keys are actually keypairs (they contain the public key) | ||
|  | * NIST P-256, prime256v1, and secp256r1 are all aliases of the same thing | ||
|  | 
 | ||
|  | 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 EC _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). | ||
|  | 
 | ||
|  | 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. | ||
|  | 
 | ||
|  | * ECDSA support EC (named curve P-256), also known as: | ||
|  |   * NIST P-256 | ||
|  |   * prime256v1 | ||
|  |   * secp256r1 | ||
|  | * PEM, DER, and JWK | ||
|  |   * Support both ASN.1 private key formats (one supported now) | ||
|  |   * Support both ASN.1 public key formats (one supported now) | ||
|  | * Vanilla node.js (ECMAScript 5.1) | ||
|  |   * No babel | ||
|  |   * No dependencies | ||
|  | 
 | ||
|  | However, there are a few areas where I'd be willing to stretch: | ||
|  | 
 | ||
|  | * Support other universally accepted EC standards | ||
|  |   * (the 384 variety is the only one that comes to mind) | ||
|  | * Support other PEM formats | ||
|  |   * (the EC-only format comes to mind) | ||
|  | * Type definition files for altscript languages | ||
|  | 
 | ||
|  | It is not a goal of this project to support any EC 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 | ||
|  | ----- | ||
|  | 
 | ||
|  | MPL-2.0 | ||
|  | 
 | ||
|  | [Terms of Use](https://therootcompany.com/legal/#terms) | | ||
|  | [Privacy Policy](https://therootcompany.com/legal/#privacy) |