Guide 开发指南

fibjs 中 X509 证书的使用

背景介绍

什么是 x509 证书

x509 证书是基于国际标准的公钥认证服务(PKI)体系中,最常用的一种数字证书格式。它能够用于认证和加密,在互联网上广泛应用于 SSL/TLS 协议以及其他类型的网络应用。x509 证书采用了公钥/私钥认证机制,并且能够保证数据传输的保密性、完整性和真实性等。

x509 证书在什么场景中用到

在互联网上,x509 证书最常用的场景是用于 TLS/SSL 协议中的证书认证,保证客户端与服务端之间传输的数据使用安全通道进行加密并且是经过验证的。x509 证书还可以用于 VPN/SSH 等基于公私钥加密的应用协议中的身份认证。

fibjs 支持 x509 证书的处理

fibjs 支持 x509 证书的处理,提供了 crypto 模块中的 X509Cert、X509Req 等类来进行证书的读取、创建和签名等操作。可以通过这些类获取证书的有效期、公钥、颁发者、主题名称等信息,以及对证书进行签名、验证等操作。同时,fibjs 还提供了 HttpsServer 类来支持 HTTPS 的证书认证和加密连接,使得在 fibjs 中使用 x509 证书变得更加容易。

X509 模块的介绍

X509 模块是什么

在 fibjs 的 crypto 模块中,提供了 X509Cert、X509Req 等类来进行 x509 证书的读取、创建和签名等操作。X509 模块是一个用于处理 x509 证书的模块,提供了对证书的解析、创建和验证等操作。

X509 模块的作用

X509 模块的作用是对 x509 证书进行操作,可以通过该模块读取已有的 x509 证书,获取证书的有效期、公钥、颁发者、主题名称等信息。同时, X509 模块也可以创建 x509 证书请求和签名证书,方式如用于 TLS/SSL 协议中的证书认证。

X509 模块的 API

以下是 X509 模块中比较重要的 API 列表:

  • X509Cert: 用于读取和操作 x509 证书的类。
  • X509Req: 用于创建 x509 证书请求的类。
  • verify: 通过 CA 证书对验证 x509 证书。
  • SslServer: 提供基于 x509 证书的认证服务的类。
  • SslSocket: 提供基于 x509 证书的认证服务的套接字收发数据操作的类。

示例代码

以下是读取 x509 证书和创建 x509 证书请求的示例代码:

1 2 3 4 5 6 7 8 9 10 11 12
const crypto = require('crypto'); // load the cert const cert = crypto.loadCert('server.crt'); console.log(cert.subject); // create x509 certificate request let pky = crypto.PKey.from(private_pem); let req = new crypto.X509Req("CN=localhost,O=fibjs", pky); let derReq = req.der(); let pemReq = req.pem(); console.log(pemReq);

以上示例代码通过 X509Cert 类读取了一个已有的 x509 证书,并输出了证书的主题名称 subject。同时,示例代码还演示了如何通过 X509Req 创建 x509 证书请求,并输出了 PEM 格式的请求信息。

X509 模块的使用

生成自签名证书

生成自签名证书的过程比较简单,一般需要完成以下步骤:

  • 生成 PKey(私钥)
  • 生成 X509Req(证书请求)
  • 使用 X509Req 生成 X509Cert(正式证书)
  • 保存证书

通过这些步骤,可以自己生成一个用于测试和开发环境的 x509 证书。下面是具体的实现:

使用以下代码创建 PKey 对象。其中,from() 方法可以通过一个 PEM 格式的字符串或者一个 Buffer 来创建 PKey 对象。

1 2
const crypto = require('crypto'); const pky = crypto.PKey.from(private_pem);

使用以下代码创建 X509Req 对象。其中,X509Req 的第一个参数是主题可分辨名称(Subject Name),字符串格式为 key1=value1,key2=value2。第二个参数是先前创建的 PKey 对象,用于证书签名。例如:

1
let xrq = new crypto.X509Req("CN=localhost,O=fibjs", pky);

使用以下代码创建 X509Cert(正式证书)。具体操作是调用 X509Req 的 sign() 方法,该方法接受三个参数:证书颁发机构的名称、用于签名的 PKey 对象、以及其他相关信息。例如,下列示例中,将 X509Req 对象签名为自签名证书,签名机构为本身,证书有效期为 10 年:

1 2 3 4 5
const opt = { notBefore: new Date(), notAfter: new Date(new Date().getTime() + 10 * 365 * 24 * 60 * 60 * 1000) }; const cert = xrq.sign("CN=localhost,O=fibjs", pky, opt);

使用以下代码将 PKey 和 X509Cert 保存到本地文件。由于证书是使用 PEM 格式保存的,因此可以使用 pem() 方法将证书对象转化为字符串,然后直接保存到文件中:

1 2 3 4 5
const fs = require('fs'); const ks = pky.pem(); // export pem format data of the private key const cs = cert.pem(); // export pem format data of the cert fs.writeFile('mycert.key', ks); // save the key fs.writeFile('mycert.pem', cs); // save the cert

以上代码完成了从生成私钥到存储自签名证书的整个过程。可以通过这个证书来测试和开发安全相关的应用程序。

加载证书

加载证书是使用 x509 证书时的一项重要操作。下面介绍如何加载证书文件和加载公钥私钥。

为了使用 x509 证书,必须首先将证书文件读取到内存中,并将其转换为 x509 证书对象。以下是如何加载证书文件的步骤:

在 fibjs 的 JavaScript 程序中,可以使用 fs 模块的相关 API 来读取文件。例如,使用以下代码读取 PEM 格式的证书文件:

1 2
const fs = require('fs'); const certData = fs.readFile('server.crt');

读取文件后,必须使用 X509Cert 对象将证书文件内容转换为 x509 证书:

1 2
const crypto = require('crypto'); const cert = new crypto.X509Cert(certData);

经过以上步骤,可以加载本地的 x509 证书文件。也可以使用 crypto.loadCert 直接读取证书:

1 2
const crypto = require('crypto'); const cert = crypto.loadCert('server.crt');

x509 证书中保存着公钥和加密后的签名信息,因此需要在使用证书时,将证书中的公钥解析出来,以方便对数据进行加密和解密。PKey 类可以将 PEM 格式的公钥/私钥字符串转换为公钥/私钥对象。可以使用以下代码读取 PEM 格式的公钥/私钥字符串,并创建 PKey 对象:

1 2
const privateKey = fs.readFile('private.pem'); // load the data from file const pKey = crypto.PKey.from(privateKey); // load from pem format data

或者使用 crypto.loadPKey 直接读取:

1 2
const crypto = require('crypto'); const pKey = crypto.loadPKey('private.pem');

经过以上步骤,可以将公钥/私钥文件转换为 PKey 对象。

解析证书

证书是 SSL/TLS 交互中重要的组成部分,用于身份身份验证和数据传输的加密。现在,我们来了解如何在 fibjs 中解析一个证书。

我们可以使用 crypto 模块的 X509Cert 类,通过读取一个 DER/PEM 格式的证书文件构建一个证书对象,紧接着可以获取证书的一些基本信息,例如获取证书的主题名称、颁发者名称、有效期等等信息。

示例代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
const crypto = require('crypto'); const cert = crypto.loadCert('path/to/cert.pem'); const subjectName = cert.subject; const issuerName = cert.issuer; const validFromDate = cert.notBefore; const expirationDate = cert.notAfter; const serialNumber = cert.serial; console.log(`证书主题名称: ${subjectName}`); console.log(`证书颁发者名称: ${issuerName}`); console.log(`证书有效期: ${validFromDate.toLocaleString()} ~ ${expirationDate.toLocaleString()}`); console.log(`证书序列号: ${serialNumber}`);

当需要使用一个证书时,我们需要验证这个证书的合法性,关键是要确定证书是由一个可信的组织颁发的。可以使用 X509Cert 中的 verify 方法来检查证书的合法性,常见的验证方式是通过验证证书的链,确保证书被受信任的 CA 颁发。

示例代码如下:

1 2 3 4 5 6 7 8 9
const caCert = crypto.loadCert('path/to/ca.crt'); const verifyResult = cert.verify(caCert); if (verifyResult !== 0) { console.error('证书验证失败', verifyResult); } else { console.log('证书验证通过'); }

在此示例代码中,我们首先读取指定的 CA 证书,生成一个 X509Cert 对象,接着使用证书对象上的 verify 方法验证需要验证的证书,并获取验证结果。你可以通过比较验证结果是否等于 0 来判断证书是否合法。如果验证结果不为 0,则说明验证失败,此时应当停止使用该证书。

使用证书

在使用 https 服务器时,需要确保使用的证书已经添加到服务器上。以下是一个简单的示例,通过 crypto 模块加载证书和私钥文件:

1 2 3 4 5 6 7 8 9 10
const http = require("http"); const crypto = require("crypto"); const cert = crypto.loadCert("server.crt"); const key = crypto.loadPKey("server.key"); const server = new http.HttpsServer(cert, key, 8443, function(req) { req.response.write(`Hello, fibjs!`); }); server.start();

在上面的示例中,我们通过 loadCert 和 loadPKey 函数加载了 server.crt 和 server.key 文件,然后使用 HttpsServer 对象创建了一个服务,并用加载的证书和密钥文件启动服务。

X509 模块的注意事项

证书的安全性

X509 模块提供了证书的创建、处理等功能,证书的安全性必须得到保障,这需要特别注意以下几点:

  • 私钥的安全性。私钥是证书的重要组成部分,必须得到严格保护。在证书的使用过程中,应该尽可能地将私钥存储在安全的地方,并合理设置访问权限。
  • 证书的传输安全。在证书的交换和使用过程中,必须采用安全的传输方式,避免证书被窃取或篡改。
  • 证书的验证安全。证书验证是确保证书有效和安全性的重要环节,必须严格按照证书的验证规则来进行验证,以避免伪造的证书误导使用者。

证书的有效期

证书的有效期是指从证书发行日期到证书过期日期之间的这段时间。证书的有效期限制了证书的使用时间,在证书过期之前,证书持有人可以使用证书,但在证书过期之后,证书将失去其有效性。

因此,在使用证书之前,必须先检查证书的有效期,以避免使用已经过期的证书。同时,在证书过期之前,应该尽早地更新证书,以确保证书的可用性。

证书的信任机制

证书的信任机制是证书能否被客户端或服务器端信任的关键因素。通常情况下,客户端或服务器端只信任由可信机构(CA)签发和承认的证书。

在使用证书之前,必须确定证书的信任问题。可以通过检查证书的颁发机构、证书的主题可分辨名称等方式来判断证书是否可信任。

证书的更新机制

证书的更新机制是确保证书一直有效并且安全的重要环节。通常情况下,证书的更新主要包括两个方面:

  • 证书过期后的更新。在证书过期后,必须重新申请证书,并按照相应的规则进行签名和验证,以确保证书的有效性。
  • 证书扩展和更新。在证书的使用过程中,如果需要扩展或更新证书的信息,可以通过重新申请证书并进行签名和验证的方式来实现。

综上所述,X509 模块提供了证书的创建、处理等功能,是确保证书安全、可信和有效的重要环节。在使用和管理证书的过程中,必须遵循相应的规则和要求,以确保证书的有效性和安全性。

👉 【添加 native 模块