tls-keygen
Version:
Generate a self-signed TLS certificate and add it to the trusted certificate store.
163 lines (114 loc) • 5.86 kB
Markdown
Generates a self-signed, trusted TLS certificate that is accepted by browsers for `localhost` development.
The generated private key (`key.pem`) and public certificate (`cert.pem`) files are compatible with Node.js and most other servers.
The generated public certificate (`cert.pem`) file is added to the native certificate store on Windows, MacOS, and Linux for automatic HTTPS and HTTP/2 browser support.
| | Chrome | Safari | Edge | Firefox |
|---------|:------:|:------:|:----:|:-------:|
| MacOS | ✅ | ✅ | | |
| Windows | ✅ | | ✅ | |
| Linux | ✅ | | | ✅ |
Note: Linux support requires the `certutil` command to be installed. On Ubuntu and Debian, run: `sudo apt-get install libnss3-tools`
## Use Cases
Easily use TLS in locally hosted websites. Using HTTP/2 or some web platform API's requires the page to be served from an `https://` origin. This tool makes it easy to generate the necessary key & certificate files.
The generated certificates are not useful in production deployments on the public internet since they are self-signed and only for local addresses. However they could be used, in combination with local DNS hijacking (e.g. `/etc/hosts` overrides) to mimick production systems locally.
## CLI
```
npx tls-keygen
```
```
npx tls-keygen "key.pem" "cert.pem" [--skip-entrust] [--add-san <name>]
```
The arguments `key.pem` and `cert.pem` are, optionally, the output destination filepaths for the TLS private key and public certificate respectively.
The `--skip-entrust` option generates the key & certificate pair without registering the certificate with the operating system certificate store.
The `--add-san <name>` option appends a single name for which this certificate is valid. The `<name>` value must be either a DNS hostname or IP address. This list is recorded in the certificate as the Subject Alternative Names (SAN).
| Type | Example |
|------|---------|
| DNS | `--add-san DNS:foo.local` |
| IPv4 | `--add-san IP:172.16.1.2` |
| IPv6 | `--add-san IP:fe80::200:5aee:feaa:20a2` |
### Output
```
Key:
🔑 /Users/seb/key.pem
Certificate:
📜 /Users/seb/cert.pem
Common Name:
- 🏷 localhost
Subject Alternative Names:
- 🏷 DNS:localhost
- 🏷 DNS:*.localhost
- 🏷 DNS:localhost.localdomain
- 🏷 IP:127.0.0.1
- 🏷 IP:0.0.0.0
- 🏷 IP:::1
- 🏷 IP:::
🔐 Done!
```
## API
### `keygen(options)`
```js
const {keygen} = require('tls-keygen')
// Returns a promise that
// resolves with `key` and `cert` file paths.
const {key, cert} = await keygen({
// Default: ./key.pem
key: '/path/to/output/key.pem',
// Default: ./cert.pem
cert: '/path/to/output/cert.pem',
// Default: localhost
commonName: 'example.net',
// Default: [
// 'DNS:localhost',
// 'DNS:*.localhost',
// 'DNS:localhost.localdomain',
// 'IP:127.0.0.1',
// 'IP:0.0.0.0',
// 'IP:::1',
// 'IP:::'
// ]
subjectAltName: [
'DNS:example.net',
'DNS:www.example.net'
],
// Set to `false` to skip adding the certificate
// to the trusted certificate store.
// Default: true
entrust: false
})
```
The default options are exported for convenience.
```js
const {
defaultKey,
defaultCert,
defaultCommonName,
defaultSubjectAltName
} = require('tls-keygen')
```
Convenience utility to generate a key & certificate for in-memory use only. Handy when writing tests that use TLS (e.g. HTTPS, HTTP/2).
Accepts the same options as `keygen()` (see above), except that the `key` and `cert` file paths are ignored.
Returns a promise that resolves to an object with fields `key` and `cert` that are two `Buffers` containing the raw key and certificate data.
```js
const {ephemeral} = require('tls-keygen')
const {key, cert} = await ephemeral(options)
// key: <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 50 ... >
// cert: <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 43 ... >
```
- **MacOS**: **Safari** and **Chrome** using *Keychain*
- **Windows**: **Edge** and **Chrome** using *Certificate Service*
- **Linux**: **Firefox** and **Chrome** using *NSS*
Note: Firefox may require a restart to accept the certificate.
Usage with clients that do not support the native operating system certificate stores is the same as regular self-signed certificates.
- Node.js: Use the `rejectUnauthorized: false` [TLS option](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
- Curl: Use the `--insecure` option (alias: `-k`).
- Firefox: Press *"Advanced"*, then *"Add Exception..."*, and finally *"Confirm Security Exception"*.
- **Fastify**: Use the [fastify-tls-keygen](https://www.npmjs.com/package/fastify-tls-keygen) plugin
- **Node.js**: Use the [`key` and `cert`](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) options with [tls.createServer](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener), [https.createServer](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener), or [http2.createSecureServer](https://nodejs.org/api/http2.html#http2_http2_createsecureserver_options_onrequesthandler)
- **Apache HTTP Server**: Use the [SSLCertificateFile](http://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcertificatefile) and [SSLCertificateKeyFile](http://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcertificatekeyfile) options
- **Nginx**: Use the [ssl_certificate_key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key) and [ssl_certificate](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) options
Made with 💝 by [Sebastiaan Deckers](https://twitter.com/sebdeckers) in 🇸🇬 Singapore.