jscert
A fast, lightweight & dependency-free NodeJS library to read, write and manipulate X.509 certificates.
WARNING: For the time being, you shouldn't pass untrusted data to the lib or unexpected things might happen to your
cat. While the lib should be working for valid data, it lacks on proper hardening of the parsing bits and proper
data validation/error handling, so maliciously crafted bits of data may cause some damage.
I may, in the future, try this lib against a fuzzer and make sure it's as safe as I can get it to be. For now, only
use the lib with data you trust!!
Install
The library is alpha-quality, potentially broken and doesn't do a lot of things.
Note: This library uses ES Modules.
pnpm i @cyyynthia/jscert
yarn add @cyyynthia/jscert
npm i @cyyynthia/jscert
Usage
Create a Certificate Signing Request
import { writeFileSync } from 'fs'
import { generateKeyPairSync } from 'crypto'
import { CertificateSigningRequest, encodePem } from '@cyyynthia/jscert'
const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 })
const dn = {
country: 'FR',
state: 'Occitanie',
locality: 'Toulouse',
organization: 'Borkenware',
organizationalUnit: 'DSI',
commonName: '*.borkenware.localhost',
emailAddress: 'cyyynthia@borkenware.com'
}
const csr = new CertificateSigningRequest(dn, privateKey)
writeFileSync('./private-key.pem', encodePem(privateKey.export({ format: 'der', type: 'pkcs1' }), 'RSA PRIVATE KEY'))
writeFileSync('./certificate-signing-request.pem', csr.toPem())
Read a Certificate Signing Request
import { readFileSync } from 'fs'
import { CertificateSigningRequest } from '@cyyynthia/jscert'
const pem = readFileSync('./certificate-signing-request.pem', 'utf8')
const csr = CertificateSigningRequest.fromPem(pem)
console.log(csr)
Turn a CSR into a self-signed Certificate
import { readFileSync } from 'fs'
import { CertificateSigningRequest } from '@cyyynthia/jscert'
const expiry = new Date(Date.now() + 365 * 86400e3)
const csr = new CertificateSigningRequest(...)
const cert = csr.createSelfSignedCertificate(expiry)
console.log(cert.toPem())
Turn a CSR into a signed Certificate
import { readFileSync } from 'fs'
import { CertificateSigningRequest, Certificate } from '@cyyynthia/jscert'
const issuerCert = Certificate.fromPem(...)
const issuerPrivateKey = ...
const expiry = new Date(Date.now() + 365 * 86400e3)
const pem = readFileSync('./certificate-signing-request.pem', 'utf8')
const csr = CertificateSigningRequest.fromPem(pem)
const cert = csr.createCertificate(issuerCert, issuerPrivateKey, expiry)
console.log(cert.toPem())
Turn a CSR into a signed Certificate
import { readFileSync } from 'fs'
import { CertificateSigningRequest, Certificate } from '@cyyynthia/jscert'
const issuerCert = Certificate.fromPem(...)
const issuerPrivateKey = ...
const pem = readFileSync('./certificate-signing-request.pem', 'utf8')
const csr = CertificateSigningRequest.fromPem(pem)
const cert = csr.sign(issuerCert, issuerPrivateKey)
console.log(cert)
Read a certificate
import { readFileSync } from 'fs'
import { Certificate } from '@cyyynthia/jscert'
const pem = readFileSync('./certificate.pem', 'utf8')
const cert = Certificate.fromPem(pem)
console.log(cert)
Verify the authenticity of a certificate
Note: the lib will only check validity period and if the signatures match. The lib will NOT check if the
certificate you pass is trusted, and the lib will always yield true
if the certificate is self-signed (as long
as we are withing its validity period). You are responsible for ensuring self-signed certificates are in any form
of trust chain.
You can check if a certificate is self-signed by checking if the selfSigned
property is true.
import { readFileSync } from 'fs'
import { Certificate } from '@cyyynthia/jscert'
const rootCert = Certificate.fromPem(readFileSync('./root-cert.pem', 'utf8'))
const cert = Certificate.fromPem(readFileSync('./certificate.pem', 'utf8'))
console.log(cert.verify(rootCert))
Decode/encode PEM
import { readFileSync } from 'fs'
import { decodePem, encodeAsn, encodePem } from '@cyyynthia/jscert'
const pem = readFileSync('./certificate-signing-request.pem', 'utf8')
console.log(decodePem(pem))
const asn = encodeAsn(...)
console.log(encodePem(asn, 'CERTIFICATE REQUEST'))
Decode/encode raw ASN.1
import { decodeAsn, encodeAsn } from '@cyyynthia/jscert'
const decoded = decodeAsn(asnBuffer)
const encoded = encodeAsn(decoded)
Inspect ASN.1
import { inspectAsn } from '@cyyynthia/jscert'
console.log(inspectAsn(asnBuffer))
const decoded = decodeAsn(asnBuffer)
console.log(inspectAsn(decoded))