354 lines
12 KiB
Markdown
354 lines
12 KiB
Markdown
pem
|
||
===
|
||
|
||
Create private keys and certificates with node.js
|
||
|
||
[](http://travis-ci.org/Dexus/pem) [](http://badge.fury.io/js/pem) [](https://www.npmjs.com/package/pem) [](https://dexus.github.io/pem/jsdoc/)
|
||
|
||
[](https://github.com/standard/standard)
|
||
|
||
## Installation
|
||
|
||
Install with npm
|
||
|
||
npm install pem
|
||
|
||
or use yarn
|
||
|
||
yarn add pem
|
||
|
||
:warning: Please make sure you have `openssl` or `libressl` already installed on your system/container, without
|
||
them `pem` will not work.
|
||
|
||
## Examples
|
||
|
||
Here are some examples for creating an SSL key/cert on the fly, and running an HTTPS server on port 443. 443 is the
|
||
standard HTTPS port, but requires root permissions on most systems. To get around this, you could use a higher port
|
||
number, like 4300, and use https://localhost:4300 to access your server.
|
||
|
||
### Basic https
|
||
|
||
```javascript
|
||
var https = require('https')
|
||
var pem = require('pem')
|
||
|
||
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
|
||
if (err) {
|
||
throw err
|
||
}
|
||
https.createServer({ key: keys.clientKey, cert: keys.certificate }, function (req, res) {
|
||
res.end('o hai!')
|
||
}).listen(443)
|
||
})
|
||
```
|
||
|
||
### Express
|
||
```javascript
|
||
var https = require('https')
|
||
var pem = require('pem')
|
||
var express = require('express')
|
||
|
||
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
|
||
if (err) {
|
||
throw err
|
||
}
|
||
var app = express()
|
||
|
||
app.get('/', function (req, res) {
|
||
res.send('o hai!')
|
||
})
|
||
|
||
https.createServer({ key: keys.clientKey, cert: keys.certificate }, app).listen(443)
|
||
})
|
||
```
|
||
|
||
## API
|
||
Please have a look into the [API documentation](https://dexus.github.io/pem/jsdoc/).
|
||
|
||
_we had to clean up a bit_
|
||
<!--
|
||
### Create a dhparam key
|
||
|
||
Use `createDhparam` for creating dhparam keys
|
||
|
||
pem.createDhparam(keyBitsize, callback)
|
||
|
||
Where
|
||
|
||
* **keyBitsize** is an optional size of the key, defaults to 512 (bit)
|
||
* **callback** is a callback function with an error object and `{dhparam}`
|
||
|
||
### Create a ecparam key
|
||
|
||
Use `createEcparam` for creating ecparam keys
|
||
|
||
pem.createEcparam(keyName, callback)
|
||
|
||
Where
|
||
|
||
* **keyName** is an optional name of the key curves name, defaults to secp256k1
|
||
* **callback** is a callback function with an error object and `{ecparam}`
|
||
|
||
### Create a private key
|
||
|
||
Use `createPrivateKey` for creating private keys
|
||
|
||
pem.createPrivateKey(keyBitsize, [options,] callback)
|
||
|
||
Where
|
||
|
||
* **keyBitsize** is an optional size of the key, defaults to 2048 (bit)
|
||
* **options** is an optional object of the cipher and password (both required for encryption), defaults {cipher:'',password:''}
|
||
(ciphers:["aes128", "aes192", "aes256", "camellia128", "camellia192", "camellia256", "des", "des3", "idea"])
|
||
* **callback** is a callback function with an error object and `{key}`
|
||
|
||
### Create a Certificate Signing Request
|
||
|
||
Use `createCSR` for creating certificate signing requests
|
||
|
||
pem.createCSR(options, callback)
|
||
|
||
Where
|
||
|
||
* **options** is an optional options object
|
||
* **callback** is a callback function with an error object and `{csr, clientKey}`
|
||
|
||
Possible options are the following
|
||
|
||
* **clientKey** is an optional client key to use
|
||
* **clientKeyPassword** the optional password for `clientKey`
|
||
* **keyBitsize** - if `clientKey` is undefined, bit size to use for generating a new key (defaults to 2048)
|
||
* **hash** is a hash function to use (either `md5`, `sha1` or `sha256`, defaults to `sha256`)
|
||
* **country** is a CSR country field
|
||
* **state** is a CSR state field
|
||
* **locality** is a CSR locality field
|
||
* **organization** is a CSR organization field
|
||
* **organizationUnit** is a CSR organizational unit field
|
||
* **commonName** is a CSR common name field (defaults to `localhost`)
|
||
* **altNames** is a list (`Array`) of subjectAltNames in the subjectAltName field (optional)
|
||
* **emailAddress** is a CSR email address field
|
||
* **csrConfigFile** is a CSR config file
|
||
|
||
### Create a certificate
|
||
|
||
Use `createCertificate` for creating private keys
|
||
|
||
pem.createCertificate(options, callback)
|
||
|
||
Where
|
||
|
||
* **options** is an optional options object
|
||
* **callback** is a callback function with an error object and `{certificate, csr, clientKey, serviceKey}`
|
||
|
||
Possible options include all the options for `createCSR` - in case `csr` parameter is not defined and a new
|
||
CSR needs to be generated.
|
||
|
||
In addition, possible options are the following
|
||
|
||
* **serviceKey** is a private key for signing the certificate, if not defined a new one is generated
|
||
* **serviceKeyPassword** Password of the service key
|
||
* **serviceCertificate** is the optional certificate for the `serviceKey`
|
||
* **serial** is the unique serial number for the signed certificate, required if `serviceCertificate` is defined
|
||
* **selfSigned** - if set to true and `serviceKey` is not defined, use `clientKey` for signing
|
||
* **csr** is a CSR for the certificate, if not defined a new one is generated
|
||
* **days** is the certificate expire time in days
|
||
* **extFile** extension config file - **without** `-extensions v3_req`
|
||
* **config** extension config file - **with** `-extensions v3_req`
|
||
|
||
### Export a public key
|
||
|
||
Use `getPublicKey` for exporting a public key from a private key, CSR or certificate
|
||
|
||
pem.getPublicKey(certificate, callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded private key, CSR or certificate
|
||
* **callback** is a callback function with an error object and `{publicKey}`
|
||
|
||
### Read certificate info
|
||
|
||
Use `readCertificateInfo` for reading subject data from a certificate or a CSR
|
||
|
||
pem.readCertificateInfo(certificate, callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded CSR or a certificate
|
||
* **callback** is a callback function with an error object and `{serial, country, state, locality, organization, organizationUnit, commonName, emailAddress, validity{start, end}, san{dns, ip, email}?, issuer{country, state, locality, organization, organizationUnit}, signatureAlgorithm, publicKeyAlgorithm, publicKeySize }`
|
||
|
||
? *san* is only present if the CSR or certificate has SAN entries.
|
||
|
||
*signatureAlgorithm, publicKeyAlgorithm and publicKeySize* only available if supportet and can parsed form openssl output
|
||
|
||
### Get fingerprint
|
||
|
||
Use `getFingerprint` to get the default SHA1 fingerprint for a certificate
|
||
|
||
pem.getFingerprint(certificate, [hash], callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded certificate
|
||
* **hash** is a hash function to use (either `md5`, `sha1` or `sha256`, defaults to `sha1`)
|
||
* **callback** is a callback function with an error object and `{fingerprint}`
|
||
|
||
### Get modulus
|
||
|
||
Use `getModulus` to get the modulus for a certificate, a CSR or a private key. Modulus can be useful to check that a Private Key Matches a Certificate
|
||
|
||
pem.getModulus(certificate, [password], [hash], callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded certificate, CSR or private key
|
||
* **password** is an optional passphrase for passpharse protected certificates
|
||
* **hash** is an optional hash function to use (up to now `md5` supported) (default: none)
|
||
* **callback** is a callback function with an error object and `{modulus}`
|
||
|
||
### Get DH parameter information
|
||
|
||
Use `getDhparamInfo` to get the size and prime of DH parameters.
|
||
|
||
pem.getDhparamInfo(dhparam, callback)
|
||
|
||
Where
|
||
|
||
* **dhparam** is a PEM encoded DH parameters string
|
||
* **callback** is a callback function with an error object and `{size, prime}`
|
||
|
||
|
||
### Export to a PKCS12 keystore
|
||
|
||
Use `createPkcs12` to export a certificate, the private key and optionally any signing or intermediate CA certificates to a PKCS12 keystore.
|
||
|
||
pem.createPkcs12(clientKey, certificate, p12Password, [options], callback)
|
||
|
||
Where
|
||
|
||
* **clientKey** is a PEM encoded private key
|
||
* **certificate** is a PEM encoded certificate
|
||
* **p12Password** is the password of the exported keystore
|
||
* **options** is an optional options object with `cipher`, (one of "aes128", "aes192", "aes256", "camellia128", "camellia192", "camellia256", "des", "des3" or "idea"), `clientKeyPassword` and `certFiles` (an array of additional certificates to include - e.g. CA certificates)
|
||
* **callback** is a callback function with an error object and `{pkcs12}` (binary)
|
||
|
||
### Read a PKCS12 keystore
|
||
|
||
Use `readPkcs12` to read a certificate, private key and CA certificates from a PKCS12 keystore.
|
||
|
||
pem.readPkcs12(bufferOrPath, [options], callback)
|
||
|
||
Where
|
||
|
||
* **bufferOrPath** is a PKCS12 keystore as a [Buffer](https://nodejs.org/api/buffer.html) or the path to a file
|
||
* **options** is an optional options object with `clientKeyPassword` which will be used to encrypt the stored key and `p12Password` which will be used to open the keystore
|
||
* **callback** is a callback function with an error object and `{key: String, cert: String, ca: Array}`
|
||
|
||
### Check a PKCS12 keystore
|
||
|
||
Use `checkPkcs12` to check a PKCS12 keystore.
|
||
|
||
pem.checkPkcs12(bufferOrPath, [passphrase], callback)
|
||
|
||
Where
|
||
|
||
* **bufferOrPath** is a PKCS12 keystore as a [Buffer](https://nodejs.org/api/buffer.html) or the path to a file
|
||
* **passphrase** is an optional passphrase which will be used to open the keystore
|
||
* **callback** is a callback function with an error object and a boolean as arguments
|
||
|
||
### Verify a certificate signing chain
|
||
|
||
Use `verifySigningChain` to assert that a given certificate has a valid signing chain.
|
||
|
||
pem.verifySigningChain(certificate, ca, callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded certificate string
|
||
* **ca** is a PEM encoded CA certificate string or an array of certificate strings
|
||
* **callback** is a callback function with an error object and a boolean as arguments
|
||
|
||
### Check a certificate file
|
||
|
||
Use `checkCertificate` to check / verify consistency of a certificate.
|
||
|
||
pem.checkCertificate(certificate, callback)
|
||
|
||
Where
|
||
|
||
* **certificate** is a PEM encoded certificate string
|
||
* **callback** is a callback function with an error object and a boolean as arguments
|
||
-->
|
||
|
||
### Custom extensions config file
|
||
|
||
You can specify custom OpenSSL extensions using the `config` or `extFile` options for `createCertificate` (or using `csrConfigFile` with `createCSR`).
|
||
|
||
`extFile` and `csrConfigFile` should be paths to the extension files. While `config` will generate a temporary file from the supplied file contents.
|
||
|
||
If you specify `config` then the `v3_req` section of your config file will be used.
|
||
|
||
The following would be an example of a Certificate Authority extensions file:
|
||
|
||
[req]
|
||
req_extensions = v3_req
|
||
distinguished_name = req_distinguished_name
|
||
|
||
[req_distinguished_name]
|
||
commonName = Common Name
|
||
commonName_max = 64
|
||
|
||
[v3_req]
|
||
basicConstraints = critical,CA:TRUE
|
||
|
||
While the following would specify subjectAltNames in the resulting certificate:
|
||
|
||
[req]
|
||
req_extensions = v3_req
|
||
|
||
[ v3_req ]
|
||
basicConstraints = CA:FALSE
|
||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||
subjectAltName = @alt_names
|
||
|
||
[alt_names]
|
||
DNS.1 = host1.example.com
|
||
DNS.2 = host2.example.com
|
||
DNS.3 = host3.example.com
|
||
|
||
Note that `createCertificate` and `createCSR` supports the `altNames` option which would be easier to use in most cases.
|
||
|
||
:warning: **Warning: If you specify `altNames` the custom extensions file will not be passed to OpenSSL.**
|
||
|
||
### Setting openssl location
|
||
|
||
In some systems the `openssl` executable might not be available by the default name or it is not included in $PATH. In this case you can define the location of the executable yourself as a one time action after you have loaded the pem module:
|
||
|
||
```javascript
|
||
var pem = require('pem')
|
||
pem.config({
|
||
pathOpenSSL: '/usr/local/bin/openssl'
|
||
})
|
||
// do something with the pem module
|
||
```
|
||
|
||
### :warning: CSR/Certificates with special chars
|
||
For more details, search in `test/pem.spec.js`: `Create CSR with specialchars config file`
|
||
|
||
If you use special chars like:
|
||
|
||
```
|
||
-!$%^&*()_+|~=`{}[]:/;<>?,.@#
|
||
```
|
||
|
||
You should know that the result mey have escaped characters when you read it in your application.
|
||
Will try to fix this in the future, but not sure.
|
||
|
||
|
||
### Special thanks to
|
||
|
||
- Andris Reinman (@andris9) - Initiator of pem
|
||
|
||
## License
|
||
|
||
**MIT**
|