如何为https web服务器创建.pem文件

101

我正在使用Node.js中的Express框架创建Web服务器。我想为Web服务器的连接使用SSL。

以下是创建HTTPS Web服务器的代码。

var app = express.createServer({
  key: fs.readFileSync('./conf/key.pem'),
  cert: fs.readFileSync('./conf/cert.pem')
});
module.exports = app;

问题:如何创建Express所需的key.pem和cert.pem文件?

3个回答

219

你需要的两个文件是一个PEM编码的SSL证书和私钥。PEM编码的证书和密钥是Base64编码的文本,并且具有类似于-----BEGIN RSA PRIVATE KEY-----的开始/结束分隔符。

要创建SSL证书,首先需要生成私钥和证书签名请求(CSR)(其中还包含公钥)。你可以通过多种方式完成这个过程,但以下是使用OpenSSL的方法。

openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem

这将导致您进入一个交互式提示符来生成一个2048位的RSA私钥和一个包含您选择在提示中输入的所有信息的CSR(通用名称是遗留位置,用于存放域名,但现代浏览器现在需要称为SubjectAlternativeName的扩展名。然而,在提交给CA时,他们会将CN值放在SAN中)。完成后,通常会将此CSR提交给受信任的证书颁发机构,一旦他们验证了您的请求,您就会收到一张证书。

如果您不关心您的证书是否被信任(通常用于开发目的),您可以创建自签名证书。要做到这一点,我们可以使用几乎相同的命令行,但是需要传递一些额外的参数。交互式提示不支持主题备用名称(SAN),大多数现代客户端都需要它,因此我们通过-addext标志将其传递到CLI。您需要将mydnsname.com更改为您所使用的正确名称。但请确保保留DNS:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -addext "subjectAltName = DNS:mydnsname.com"

这将为您提供一个证书(有效期为10年)和密钥对,您可以在您发布的代码片段中使用它们。


3
客户端证书和密钥怎么处理? - nkint
1
这篇文章已经完成,运行他贴出的两个命令即可获得密钥和证书。客户端不建立信任,只有服务器建立信任。 - Ninjaxor
@paul,请问这些.pem密钥和证书是在哪里生成的?我的意思是在哪个目录下?我正在使用Ubuntu 14。 - StormTrooper
2
它们将写入您shell的当前工作目录。 - Paul Kehrer
2
请注意,以此方式生成的自签名证书为版本1,包含CN,但不包含SAN。"自Chrome 58版本起,SSL证书需要使用主题备用名称(SAN)而非流行的通用名称(CN),因此已删除CN支持。" 使用openssl修复Chrome 58+ [missing_subjectAltName]问题 - Zhiyong
显示剩余3条评论

13

按照以下步骤进行:

  1. 创建文件夹以存储您的密钥和证书:

    mkdir conf


  1. 进入该目录:

    cd conf


  1. 获取ca.cnf文件作为配置快捷方式:

    wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf


  1. 使用此配置创建新的证书授权机构:

    openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem


  1. 现在我们有了位于 ca-key.pemca-cert.pem 中的证书授权机构,让我们为服务器生成私钥:

    openssl genrsa -out key.pem 4096


  1. 获取server.cnf文件作为配置快捷方式:

    wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf


  1. 使用此配置生成证书签名请求:

    openssl req -new -config server.cnf -key key.pem -out csr.pem


  1. 签署请求:

    openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem

我在这里找到了该过程,以及有关如何使用这些证书的更多信息。


1

另一种选择是使用pem库中的createCertificate类方法生成证书。

具体步骤如下:

如果您的系统中没有安装openssl,您需要先安装它。例如,对于Windows 10,可以在此处找到已编译版本的源代码(似乎是最开放的):https://curl.se/windows/。有关如何编译和保护它的说明在这里:https://wiki.openssl.org/index.php/Binaries。源代码请参见https://www.openssl.org/community/binaries.html。对于Windows系统,您可能需要将openssl.bin文件所在的目录添加到系统环境路径变量中(https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/),或者将文件位置传递给PEM库。

使用以下命令安装pem(文档在此处:https://github.com/Dexus/pem

npm i pem

在服务器根目录的命令行中。

从文档中可以看到,只需执行以下简单命令即可创建带密钥的简单 https 服务器:

const https = require('https')
const pem = require('pem')

pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
  if (err) {
    throw err
  }
  https.createServer({ key: keys.clientKey, cert: keys.certificate }, (req, res)  => {
    res.end('o hai!')
  }).listen(443)
})

或者使用express(在服务器根目录的命令行中输入以下命令: npm i express):

const https = require('https')
const pem = require('pem')
const express = require('express')

pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
  if (err) {
    throw err
  }
  const app = express()

  app.get('/', (req, res) => {
    res.send('o hai!')
  })

  https.createServer({ key: keys.clientKey, cert: keys.certificate }, app).listen(443)
})

将变量从var改为const,将函数改为箭头函数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接