注意,授信必须在cmd的管理员模式下运行,如果重复授信,必须在【运行】里面输入【certmgr.msc】打开certmgr证书管理界面,然后找到【受信任的根证书颁发机构】-【证书】,找到【localhost】 ,删除后从新执行下面代码
JavaScript
// 引入所需模块
const https = require('https');
const fs = require('fs');
const forge = require('node-forge');
const { exec } = require('child_process');
const path = require('path');
let certPem="";
let keyPem="";
// 连接多个路径片段
const certPath = path.join(__dirname, 'ssl-cert.pem');
const keyPath = path.join(__dirname, 'ssl-key.pem');
// 将证书添加到Windows信任存储的函数
function addCertificateToTrustStore(certPath) {
const cmd = `certutil -addstore root ${certPath}`;
exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error(`执行错误: ${error}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
}
// 生成自签名证书函数
function generateSelfSignedCertificate() {
const keys = forge.pki.rsa.generateKeyPair(2048); // 生成密钥对
const cert = forge.pki.createCertificate(); // 创建证书对象
cert.publicKey = keys.publicKey; // 设置公钥
cert.serialNumber = '01'; // 序列号
cert.validity.notBefore = new Date(); // 证书开始时间
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 99); // 有效期1年
// 设置证书主体信息
const attrs = [
{ name: 'commonName', value: 'localhost' },
{ name: 'countryName', value: 'CN' },
{ name: 'organizationName', value: 'MyCompany' },
];
cert.setSubject(attrs); // 证书主题
cert.setIssuer(attrs); // 自签名,颁发者与主题一致
// 添加扩展
cert.setExtensions([
{ name: 'basicConstraints', cA: true },
{
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
keyEncipherment: true,
},
{
name: 'subjectAltName',
altNames: [{ type: 2, value: 'localhost' }],
},
]);
// 使用私钥对证书签名
cert.sign(keys.privateKey, forge.md.sha256.create());
// PEM 格式化密钥和证书
const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey);
const certPem = forge.pki.certificateToPem(cert);
return { key: privateKeyPem, cert: certPem };
}
if (!fs.existsSync(certPath) && !fs.existsSync(keyPath)) {
console.log('证书或密钥文件不存在,正在生成...');
// 保存证书到文件(可选)
// 生成SSL证书
const { key, cert } = generateSelfSignedCertificate();
fs.writeFileSync(certPath, cert);
fs.writeFileSync(keyPath, key);
// 调用函数,传入证书文件的路径
addCertificateToTrustStore(certPath);
certPem=cert;
keyPem=key;
}else{
console.log('证书和密钥文件已存在,正在读取...');
// 读取证书和密钥文件
certPem= fs.readFileSync(certPath, 'utf8');
keyPem = fs.readFileSync(keyPath, 'utf8');
}
setTimeout(function (){
// 创建HTTPS服务器
https.createServer({ key: keyPem, cert: certPem }, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Hello, HTTPS===${Date.now()}`);
}).listen(443, () => {
console.log('HTTPS 服务器已启动:https://localhost');
});
},2000)