笔记记录:NodeJS生成本地证书

816 阅读2分钟

使用node-forge生成证书和私钥的方式可以替换openssl生成证书和私钥的方式。node-forge是一个纯JavaScript库,可以在Node.js环境中使用,提供了生成证书和私钥的功能。而openssl是一个独立的命令行工具,用于处理各种加密相关的任务,包括生成证书和私钥。

在某些情况下,使用node-forge可能更方便,因为您可以直接在Node.js代码中生成证书和私钥,而无需依赖外部命令行工具。此外,node-forge可以在不同平台上提供一致的功能,而无需考虑openssl在不同系统上的安装和配置问题。

安装node-forge

npm i node-forge
const forge = require('node-forge')
const fs = require('fs')

const createSelfSignedCert = () => {
  // 生成RSA密钥对,密钥长度为2048位
  const keys = forge.pki.rsa.generateKeyPair(2048)

  // 创建一个新的X.509证书
  const cert = forge.pki.createCertificate()
  // 将公钥设置为生成的公钥
  cert.publicKey = keys.publicKey
  // 设置证书的序列号
  cert.serialNumber = '01'

  // 设置证书的有效期,从当前时间开始,有效期为1年
  cert.validity.notBefore = new Date()
  cert.validity.notAfter = new Date()
  cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1)

  // 定义证书的主题属性,包括通用名称、国家名称、州/省名称、地区名称、组织名称等
  const attrs = [
    { name: 'commonName', value: 'localhost' },
    { name: 'countryName', value: 'US' },
    { shortName: 'ST', value: 'California' },
    { name: 'localityName', value: 'San Francisco' },
    { name: 'organizationName', value: 'My Company' },
    { shortName: 'OU', value: 'My Company' }
  ]

  // 设置证书的主题和颁发者属性
  cert.setSubject(attrs)
  cert.setIssuer(attrs)

  // 设置证书的扩展属性,如基本约束、密钥用途、扩展密钥用途等
  cert.setExtensions([
    {
      name: 'basicConstraints',
      cA: true
    },
    {
      name: 'keyUsage',
      keyCertSign: true,
      digitalSignature: true,
      nonRepudiation: true,
      keyEncipherment: true,
      dataEncipherment: true
    },
    {
      name: 'extKeyUsage',
      serverAuth: true,
      clientAuth: true,
      codeSigning: true,
      emailProtection: true,
      timeStamping: true
    },
    {
      name: 'nsCertType',
      client: true,
      server: true,
      email: true,
      objsign: true,
      sslCA: true,
      emailCA: true,
      objCA: true
    }
  ])

  // 使用生成的私钥自签名证书
  cert.sign(keys.privateKey)

  // 将生成的私钥和证书转换为PEM格式
  const pem = {
    privateKey: forge.pki.privateKeyToPem(keys.privateKey),
    certificate: forge.pki.certificateToPem(cert)
  }

  // 返回PEM格式的私钥和证书
  return pem
}

// 将PEM格式的私钥和证书写入本地文件
const savePemFiles = (privateKey, certificate) => {
  fs.writeFileSync('privateKey.pem', privateKey)
  fs.writeFileSync('certificate.pem', certificate)
}

const { privateKey, certificate } = createSelfSignedCert()
savePemFiles(privateKey, certificate)