如何对 HTTPS Node.js 服务器使用自签名证书?

2024-01-23

我已经开始为 API 编写一个包装器,该 API 要求所有请求都通过 HTTPS 进行。我不想在开发和测试实际 API 时向其发出请求,而是想在本地运行自己的服务器来模拟响应。

我对如何生成创建 HTTPS 服务器并向其发送请求所需的证书感到困惑。

我的服务器看起来像这样:

var options = {
  key: fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
};

https.createServer(options, function(req, res) {
  res.writeHead(200);
  res.end('OK\n');
}).listen(8000);

pem 文件是通过以下命令生成的:

openssl genrsa 1024 > key.pem
openssl req -x509 -new -key key.pem > cert.pem

请求看起来像这样:

var options = {
  host: 'localhost',
  port: 8000,
  path: '/api/v1/test'
};

https.request(options, function(res) {
  res.pipe(process.stdout);
}).end();

通过这个设置我得到Error: DEPTH_ZERO_SELF_SIGNED_CERT,所以我想我需要添加一个ca请求的选项。

所以我的问题是我应该如何生成以下内容:

  1. 服务器key?
  2. 服务器cert?
  3. The ca对于请求?

我已经阅读了一些有关使用 openssl 生成自签名证书的内容,但似乎无法理解它并弄清楚在节点代码中的何处使用哪些密钥和证书。

Update

API 提供了一个 CA 证书来代替默认证书。以下代码使用他们的证书工作,这就是我想在本地重现的代码。

var ca = fs.readFileSync('./certificate.pem');

var options = {
  host: 'example.com',
  path: '/api/v1/test',
  ca: ca
};
options.agent = new https.Agent(options);

https.request(options, function(res) {
  res.pipe(process.stdout);
}).end();

更新(2018 年 11 月):你need自签名证书?

或者真正的证书会让工作做得更好吗?您考虑过其中任何一个吗?

  • 让我们通过以下方式加密Greenlock.js https://git.coolaj86.com/coolaj86/greenlock-express.js
  • 让我们通过以下方式加密https://greenlock.domains https://greenlock.domains
  • 本地主机中继服务,例如https://telebit.cloud https://telebit.cloud

(注:Let's Encrypt还可以向私有网络颁发证书)

投屏

https://coolaj86.com/articles/how-to-create-a-csr-for-https-tls-ssl-rsa-pems/ https://coolaj86.com/articles/how-to-create-a-csr-for-https-tls-ssl-rsa-pems/

完整的工作示例

  • 创建证书
  • 运行node.js服务器
  • Node.js 客户端中没有警告或错误
  • cURL 中没有警告或错误

https://github.com/coolaj86/nodejs-self-signed-certificate-example https://github.com/coolaj86/nodejs-self-signed-certificate-example

Using localhost.greenlock.domains例如(它指向 127.0.0.1):

服务器.js

'use strict';

var https = require('https')
  , port = process.argv[2] || 8043
  , fs = require('fs')
  , path = require('path')
  , server
  , options
  ;

require('ssl-root-cas')
  .inject()
  .addFile(path.join(__dirname, 'server', 'my-private-root-ca.cert.pem'))
  ;

options = {
  // this is ONLY the PRIVATE KEY
  key: fs.readFileSync(path.join(__dirname, 'server', 'privkey.pem'))
  // You DO NOT specify `ca`, that's only for peer authentication
//, ca: [ fs.readFileSync(path.join(__dirname, 'server', 'my-private-root-ca.cert.pem'))]
  // This should contain both cert.pem AND chain.pem (in that order) 
, cert: fs.readFileSync(path.join(__dirname, 'server', 'fullchain.pem'))
};


function app(req, res) {
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, encrypted world!');
}

server = https.createServer(options, app).listen(port, function () {
  port = server.address().port;
  console.log('Listening on https://127.0.0.1:' + port);
  console.log('Listening on https://' + server.address().address + ':' + port);
  console.log('Listening on https://localhost.greenlock.domains:' + port);
});

客户端.js

'use strict';

var https = require('https')
  , fs = require('fs')
  , path = require('path')
  , ca = fs.readFileSync(path.join(__dirname, 'client', 'my-private-root-ca.cert.pem'))
  , port = process.argv[2] || 8043
  , hostname = process.argv[3] || 'localhost.greenlock.domains'
  ;

var options = {
  host: hostname
, port: port
, path: '/'
, ca: ca
};
options.agent = new https.Agent(options);

https.request(options, function(res) {
  res.pipe(process.stdout);
}).end();

以及制作证书文件的脚本:

制作证书.sh

#!/bin/bash
FQDN=$1

# make directories to work from
mkdir -p server/ client/ all/

# Create your very own Root Certificate Authority
openssl genrsa \
  -out all/my-private-root-ca.privkey.pem \
  2048

# Self-sign your Root Certificate Authority
# Since this is private, the details can be as bogus as you like
openssl req \
  -x509 \
  -new \
  -nodes \
  -key all/my-private-root-ca.privkey.pem \
  -days 1024 \
  -out all/my-private-root-ca.cert.pem \
  -subj "/C=US/ST=Utah/L=Provo/O=ACME Signing Authority Inc/CN=example.com"

# Create a Device Certificate for each domain,
# such as example.com, *.example.com, awesome.example.com
# NOTE: You MUST match CN to the domain name or ip address you want to use
openssl genrsa \
  -out all/privkey.pem \
  2048

# Create a request from your Device, which your Root CA will sign
openssl req -new \
  -key all/privkey.pem \
  -out all/csr.pem \
  -subj "/C=US/ST=Utah/L=Provo/O=ACME Tech Inc/CN=${FQDN}"

# Sign the request from Device with your Root CA
openssl x509 \
  -req -in all/csr.pem \
  -CA all/my-private-root-ca.cert.pem \
  -CAkey all/my-private-root-ca.privkey.pem \
  -CAcreateserial \
  -out all/cert.pem \
  -days 500

# Put things in their proper place
rsync -a all/{privkey,cert}.pem server/
cat all/cert.pem > server/fullchain.pem         # we have no intermediates in this case
rsync -a all/my-private-root-ca.cert.pem server/
rsync -a all/my-private-root-ca.cert.pem client/

# create DER format crt for iOS Mobile Safari, etc
openssl x509 -outform der -in all/my-private-root-ca.cert.pem -out client/my-private-root-ca.crt

例如:

bash make-certs.sh 'localhost.greenlock.domains'

希望这能为这件事钉上棺材。

还有更多解释:https://github.com/coolaj86/node-ssl-root-cas/wiki/Painless-Self-Signed-Certificates-in-node.js https://github.com/coolaj86/node-ssl-root-cas/wiki/Painless-Self-Signed-Certificates-in-node.js

在 iOS Mobile Safari 上安装私有证书

您需要创建 DER 格式的根 ca 证书的副本,扩展名为 .crt:

# create DER format crt for iOS Mobile Safari, etc
openssl x509 -outform der -in all/my-private-root-ca.cert.pem -out client/my-private-root-ca.crt

然后您可以简单地通过您的网络服务器提供该文件。单击该链接时,系统会询问您是否要安装证书。

有关其工作原理的示例,您可以尝试安装 MIT 的证书颁发机构:https://ca.mit.edu/mitca.crt https://ca.mit.edu/mitca.crt

相关示例

  • https://github.com/coolaj86/nodejs-ssl-example https://github.com/coolaj86/nodejs-ssl-example
  • https://github.com/coolaj86/nodejs-ssl-trusted-peer-example https://github.com/coolaj86/nodejs-ssl-trusted-peer-example
  • https://github.com/coolaj86/node-ssl-root-cas https://github.com/coolaj86/node-ssl-root-cas
  • https://github.com/coolaj86/nodejs-https-sni-vhost-example https://github.com/coolaj86/nodejs-https-sni-vhost-example
    • (同一服务器上具有 SSL 的多个虚拟主机)
  • https://telebit.cloud https://telebit.cloud
    • (获取真正的 SSL 证书,您今天可以使用它在本地主机上进行测试)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何对 HTTPS Node.js 服务器使用自签名证书? 的相关文章

  • 将base64图像转换为Node Js中的文件

    我是 Node Js 新手 我需要包含用户的个人资料图片 我从 IOS 应用程序收到 Base64 图像的请求 我需要将其存储在 images 文件夹中并将图像路径保存在 mongodb 数据库中 我使用了以下代码 var bitmap n
  • 如何使用 NodeJS 和 Express 为 OpenShift 应用程序配置路由

    我是 OpenShift 新手 我需要一些帮助来在 OpenShift 上配置我的应用程序的路由 这是我尝试部署的 NodeJS Express 应用程序中的端口和 IP 配置 const server port process env O
  • 使用 Node-sass 缩小 CSS

    我在 NodeJS 项目中使用 SCSS 并让我的脚本使用以下命令将所有单独的 SCSS 文件转换为单个 CSS 文件 node sass w public css scss style scss public css style css
  • 有没有办法修复 package-lock.json lockfileVersion 以便 npm 使用特定格式?

    如果两个不同的开发人员在最初使用package lock json lockfileVersion 1 当使用 npm 7x 的开发人员安装新软件包时 似乎package lock json是使用重新创建的 lockfileVersion
  • 在 MongoDB 中删除时自动删除引用对象

    假设我有一个这样的架构 var Person new Schema name String var Assignment new Schema name String person ObjectID 如果我删除一个人 仍然可能会留下引用不存
  • ASP.NET - 将所有 https 请求重写为 http

    我的问题正是所提出的问题here https stackoverflow com questions 16276860 iis 7 adding ssl to one site all other sites responds to htt
  • 使用 puppeteer 配置 PDF 页面宽度

    我正在尝试使用 puppeteer 生成 pdf 但生成的 pdf 宽度很大 我想要一个 pdf 文件 它在一页中显示所有内容 并且宽度必须为 4 8 厘米 其中页面高度可以是其内容的任何长度 我在pdf中添加了配置 path filePa
  • 错误:找不到进程“node.exe”

    完整的错误是 ERROR The process node exe not found The filename directory name or volume label syntax is incorrect Finished in
  • 我可以在 Express POST 请求中进行 DOM 操作吗?

    我正在使用基本的 HTML CSS 前端 目前有一个登陆页面 上面有一个表单 可将 一些数据发送到数据库 当请求完成后 它期待某种响应 在这种情况下 我正在重新渲染页面 但是 我想用某种感谢消息替换表单 以便用户知道它已正确发送 我尝试过简
  • Android WebView setCertificate 问题 SSL 问题

    我看过很多关于 SSL 错误的帖子和信息 并且我自己也偶然发现了一个 我尝试使用 GlobalSign CA BE 证书通过 Android WebView 访问网页 但收到不受信任的错误 对于大多数手机来说 处理这个问题效果很好 只需告诉
  • 如何使用startsWith过滤并获取每个对象键的值?

    我试图通过获取每个键来过滤对象checkpoint并输出其值 目前 我只能输出键而不是值 下面 我有一个简单的对象 我正在使用过滤器和startsWith 我怎样才能得到这些值呢 var data practicals 0 checkpoi
  • mongodb/node.js 中单文档并发读写操作的问题

    编辑 6 15我尝试运行相同的代码 在调用之前添加延迟 doSafePush 再次收到 ConcurrencyDBError 时 即执行return when resolve wait delay 35 then function doSa
  • MongoDB - 在父文档中填充 GridFS 文件元数据

    我使用 NodeJS 与 Express MongoDB Mongoose 和 GridFS 来上传和检索文件 我想通过 ID 引用其他文档中的文件 并在查询其他文档时填充文件元数据 例如 如果我有一个包含这样的文档的 用户 集合 id O
  • 使用 mongoose 更新 mongoDb 中数组内的对象[重复]

    这个问题在这里已经有答案了 我正在 MongoDB 上工作 以更新 MongoDB 集合中数组内部的对象值 我的收藏就像 id ObjectId 59b7e839200a5c00ee2d2851 player New playesList
  • Node/Express 4.0 中可以声明全局变量吗

    我有多个需要访问数据库的路线 对于开发我使用本地数据库 显然生产我使用托管数据库 唯一的问题是每次我去推送版本时我都必须手动更改数据库链接 e g var mongodb require mongojs connect urlhere Co
  • Stripe 创建使用记录错误 - 时间戳必须早于订阅的当前周期结束时间 - Date.now()?

    我正在尝试为按计量计划的客户创建条带使用记录 当我在请求中使用时间戳 Date now 时 我收到的错误是 无法使用此时间戳创建使用记录 因为时间戳必须早于订阅的当前周期结束时间 这似乎是不言自明的 但考虑到订阅的当前周期结束时间还剩 14
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • Android 版 Qt 和 BoringSSL

    我正在开发一个基于 Qt 的 Android 应用程序 它使用 QSslSocket 下载数据 由于 Android 从 OpenSSL 转向 BoringSSL 因为依赖 OpenSSL 库的 Marshmallow Qt 程序在 And
  • 使用 CustomBinding 的 WCF 服务配置 HTTPS

    我需要 WCF 服务上的自定义绑定 以允许我将原始内容传递到 WCFRest 服务 效果很好 但我无法让它接受传输级安全性 我想要 https 和 basicauthentication 就像我在其他地方使用的那样 端点看起来像这样
  • Node Js - 识别请求是来自移动设备还是非移动设备

    我对 Node js 还是个新手 是否有任何解决方法或方法如何使用 Node js 识别来自客户端的请求是来自移动设备还是非移动设备 因为我现在正在做的是我想根据设备类型 移动 桌面 限制对某些 API 的访问 我在服务器端使用restif

随机推荐