简体中文
Windows 本地 HTTPS 证书生成指南
背景
当主域名(如 xxxx.com)配置了 HSTS(HTTP Strict Transport Security)或被加入浏览器 HSTS Preload List 时,所有子域名(包括本地 hosts 配置的 local.xxxx.com)都会被浏览器强制使用 HTTPS 访问。
此时本地
快速开始:一键脚本(推荐)
准备工作
以 管理员身份 打开 PowerShell 或 Windows 终端确定你的项目目录路径(如 D:\projects\my-app)
创建脚本文件
在项目根目录下新建 生成证书.ps1,内容如下:
# ============================================
# 本地 HTTPS 自签名证书一键生成脚本(Windows)
# 使用方法:右键 → 使用 PowerShell 运行(需管理员权限)
# ============================================
# === 配置区:根据你的实际情况修改 ===
$domain = "local.xxxx.com" # 本地开发域名
$certFriendly = "local.xxxx.com dev cert" # 证书友好名称
$projectPath = "D:\projects\my-app" # 项目根目录路径
$pfxPassword = "123456" # pfx 文件密码,本地用随便设
$validYears = 10 # 证书有效期(年)
# ===================================
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " 本地 HTTPS 证书一键生成工具" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# 检查管理员权限
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host "❌ 请以管理员身份运行此脚本!" -ForegroundColor Red
Write-Host " 右键脚本 → 使用 PowerShell 运行(管理员)" -ForegroundColor Yellow
Read-Host "按回车键退出"
exit 1
}
# 检查项目目录是否存在
if (-not (Test-Path $projectPath)) {
Write-Host "❌ 项目目录不存在: $projectPath" -ForegroundColor Red
Read-Host "按回车键退出"
exit 1
}
# 1. 生成自签名证书
Write-Host "📝 正在生成自签名证书..." -ForegroundColor Yellow
try {
$cert = New-SelfSignedCertificate `
-DnsName $domain, "localhost", "127.0.0.1" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-FriendlyName $certFriendly `
-NotAfter (Get-Date).AddYears($validYears) `
-KeyUsage DigitalSignature, KeyEncipherment `
-Type SSLServerAuthentication
Write-Host "✅ 证书生成成功" -ForegroundColor Green
Write-Host " 指纹: $($cert.Thumbprint)"
Write-Host " 有效期至: $($cert.NotAfter)"
} catch {
Write-Host "❌ 证书生成失败: $_" -ForegroundColor Red
Read-Host "按回车键退出"
exit 1
}
# 2. 安装到受信任根证书颁发机构
Write-Host ""
Write-Host "🔒 正在安装到受信任根证书颁发机构..." -ForegroundColor Yellow
try {
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
)
$rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$rootStore.Add($cert)
$rootStore.Close()
Write-Host "✅ 已安装到受信任根证书颁发机构" -ForegroundColor Green
} catch {
Write-Host "❌ 安装到根证书失败: $_" -ForegroundColor Red
}
# 3. 创建 cert 目录并导出 pfx
Write-Host ""
Write-Host "📦 正在导出 PFX 证书文件..." -ForegroundColor Yellow
$certDir = Join-Path $projectPath "cert"
New-Item -ItemType Directory -Path $certDir -Force | Out-Null
$pfxPath = Join-Path $certDir "$domain.pfx"
$securePwd = ConvertTo-SecureString -String $pfxPassword -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath $pfxPath -Password $securePwd | Out-Null
Write-Host "✅ PFX 文件已导出: $pfxPath" -ForegroundColor Green
# 4. 尝试用 OpenSSL 提取 pem 和 key(如果系统有)
$hasOpenSsl = Get-Command openssl -ErrorAction SilentlyContinue
if ($hasOpenSsl) {
Write-Host ""
Write-Host "🔑 检测到 OpenSSL,正在提取 .pem 和 .key 文件..." -ForegroundColor Yellow
Push-Location $certDir
openssl pkcs12 -in "$domain.pfx" -clcerts -nokeys -out "$domain.pem" -passin "pass:$pfxPassword" 2>$null
openssl pkcs12 -in "$domain.pfx" -nocerts -nodes -out "$domain-key.pem" -passin "pass:$pfxPassword" 2>$null
Pop-Location
Write-Host "✅ 已提取 $domain.pem 和 $domain-key.pem" -ForegroundColor Green
} else {
Write-Host ""
Write-Host "⚠️ 未检测到 OpenSSL,将直接使用 PFX 文件配置 Vite" -ForegroundColor Yellow
Write-Host " (Vite 原生支持 pfx 格式,无需转换)"
}
# 输出总结
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
Write-Host " 🎉 全部完成!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host ""
Write-Host "证书文件位置:"
Write-Host " PFX: $pfxPath"
if ($hasOpenSsl) {
Write-Host " PEM: $(Join-Path $certDir "$domain.pem")"
Write-Host " KEY: $(Join-Path $certDir "$domain-key.pem")"
}
Write-Host ""
Write-Host "接下来请在 vite.config.js 中配置 https," -ForegroundColor Cyan
Write-Host "配置示例见同目录下的 Vite 配置说明。" -ForegroundColor Cyan
Write-Host ""
Read-Host "按回车键退出"2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
运行脚本
- 修改脚本顶部的 配置区(域名、项目路径等)
- 右键脚本文件 → "使用 PowerShell 运行"(需管理员权限)
- 等待执行完成
手动分步操作(不用脚本)
如果你不想用脚本,也可以按以下步骤手动操作。
步骤 1:以管理员身份打开 PowerShell
右键开始菜单 → "终端 (管理员)" 或 "Windows PowerShell (管理员)"。
步骤 2:生成自签名证书
New-SelfSignedCertificate `
-DnsName "local.xxxx.com", "localhost", "127.0.0.1" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-FriendlyName "local.xxxx.com dev cert" `
-NotAfter (Get-Date).AddYears(10)2
3
4
5
执行成功后,复制输出的 指纹(Thumbprint)。
步骤 3:查找证书(如果忘了指纹)
Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.FriendlyName -eq "local.xxxx.com dev cert" }步骤 4:安装到受信任根证书颁发机构
$cert = Get-Item -Path "Cert:\LocalMachine\My\你的证书指纹"
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
)
$rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$rootStore.Add($cert)
$rootStore.Close()2
3
4
5
6
7
8
9
弹出确认框时选择 "是"。
步骤 5:导出 PFX 文件
# 进入项目目录
cd D:\projects\my-app
# 创建 cert 目录
New-Item -ItemType Directory -Path cert -Force
# 导出 pfx
$cert = Get-Item -Path "Cert:\LocalMachine\My\你的证书指纹"
$pwd = ConvertTo-SecureString -String "123456" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "cert\local.xxxx.com.pfx" -Password $pwd2
3
4
5
6
7
8
9
10
Vite 配置 HTTPS
方式 A:使用 PFX 文件(推荐,无需 OpenSSL)
修改 vite.config.js(或 vite.config.ts):
import { defineConfig } from 'vite'
import fs from 'fs'
// import vue from '@vitejs/plugin-vue' // Vue 项目
// import react from '@vitejs/plugin-react' // React 项目
export default defineConfig({
// plugins: [vue()],
server: {
host: 'local.xxxx.com',
port: 5173,
https: {
pfx: fs.readFileSync('./cert/local.xxxx.com.pfx'),
passphrase: '123456', // 你设置的 pfx 密码
},
// 后端代理配置(按需添加)
// proxy: {
// '/api': {
// target: 'https://api.xxxx.com',
// changeOrigin: true,
// }
// }
},
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
方式 B:使用 PEM + KEY 文件(需已通过 OpenSSL 转换)
import { defineConfig } from 'vite'
import fs from 'fs'
export default defineConfig({
server: {
host: 'local.xxxx.com',
port: 5173,
https: {
key: fs.readFileSync('./cert/local.xxxx.com-key.pem'),
cert: fs.readFileSync('./cert/local.xxxx.com.pem'),
},
},
})2
3
4
5
6
7
8
9
10
11
12
13
方式 C:使用 @vitejs/plugin-basic-ssl 插件(零配置快速尝鲜)
如果你只是想临时快速验证一下,不想生成证书、也不想折腾系统证书库,可以用 Vite 官方提供的 @vitejs/plugin-basic-ssl 插件。它会在每次启动时自动生成一张自签名证书,完全零配置。
安装插件
npm install @vitejs/plugin-basic-ssl -D配置 vite.config.js
import { defineConfig } from 'vite'
import basicSsl from '@vitejs/plugin-basic-ssl'
// import vue from '@vitejs/plugin-vue' // Vue 项目
// import react from '@vitejs/plugin-react' // React 项目
export default defineConfig({
plugins: [
basicSsl(),
// vue(),
// react(),
],
server: {
host: 'local.xxxx.com',
port: 5173,
https: true, // 开启 HTTPS
},
})2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
启动访问
npm run dev打开浏览器访问:https://local.xxxx.com:5173
⚠️ 注意:第一次打开时浏览器会提示"您的连接不是私密连接",因为这是自动生成的自签名证书,系统不信任。
解决方法:点击页面上的 "高级" → "继续前往 local.xxxx.com(不安全)" 即可正常访问。每次重新启动 dev 服务证书都会重新生成,可能需要重复此操作。
优缺点
| 优点 | 缺点 |
|---|---|
| ✅ 零配置,装完插件就能用 | ❌ 浏览器始终报"不安全",需手动点继续 |
| ✅ 不需要生成和管理证书文件 | ❌ 每次重启 dev 可能重新生成证书,体验不稳定 |
| ✅ 跨平台,任何系统都能用 | ❌ 某些对证书要求严格的场景(如 iframe 嵌入、某些 API)可能无法使用 |
| ✅ 适合临时快速验证 | ❌ 不适合长期日常开发 |
适用场景
- 临时调试一个 HTTPS 相关的小问题
- 刚接手项目,想先跑起来看看效果
- 对浏览器证书警告不敏感的场景
💡 提示:如果长期开发使用,还是推荐方式 A(PowerShell 自签名证书 + 安装到根证书),一次配置终身受用,浏览器地址栏是干净的小锁图标。
启动访问
npm run dev打开浏览器访问:https://local.xxxx.com:5173
PowerShell / mkcert 方案下地址栏会显示 🔒 小锁图标,证书完全受信任;basic-ssl 插件方案需手动点击"继续前往"。
常见问题
Q1: Firefox 浏览器仍然提示不安全?
Firefox 使用自己独立的证书库,不会自动读取系统根证书。需要手动导入:
- Firefox 设置 → 隐私与安全 → 安全 → 证书 → 查看证书
- 切换到 "证书颁发机构" 标签
- 点击 "导入" → 选择 cert\local.xxxx.com.pem 文件
- 勾选 "信任此 CA 以标识网站" → 确定
Q2: 怎么删除已生成的证书?
# 删除个人存储中的证书
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.FriendlyName -eq "local.xxxx.com dev cert" } | Remove-Item
# 删除根证书中的(需要先找到指纹)
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.FriendlyName -eq "local.xxxx.com dev cert" } | Remove-Item2
3
4
5
Q3: 证书过期了怎么办?
重新执行一次生成脚本即可,旧证书可以删掉也可以保留。
Q4: 可以给多个域名用同一张证书吗?
可以,在 -DnsName 参数中添加所有需要的域名即可:
-DnsName "local.xxxx.com", "dev.xxxx.com", "test.xxxx.com", "localhost", "127.0.0.1"Q5: hosts 文件怎么配置?
打开 C:\Windows\System32\drivers\etc\hosts(需要管理员权限编辑),添加一行:
127.0.0.1 local.xxxx.com保存后,在命令行执行 ipconfig /flushdns 刷新 DNS 缓存。
方案对比
| 对比项 | PowerShell 原生方案 | mkcert | @vitejs/plugin-basic-ssl |
|---|---|---|---|
| 需要安装额外工具 | ❌ 不需要 | ✅ 需要安装 mkcert | ✅ 需要 |
| 操作复杂度 | 中等 | 简单 | 最简单 |
| 跨平台 | 仅 Windows | Win/Mac/ | 跨平台 |
| 浏览器信任 | 安装到根证书后信任 | 自动信任 | ❌ 始终报不安全,需手动跳过 |
| 证书有效期 | 自定义(默认 10 年) | 默认几年 | 每次启动重新生成 |
| 地址栏小锁 | ✅ 有 | ✅ 有 | ❌ 没有,显示“不安全” |
| 推荐场景 | 不想装额外工具、长期开发 | 多项目/多机器复用、长期开发 | 临时快速验证、跑通即可 |
相关命令速查
| 对比项 | PowerShell 原生方案 | mkcert | @vitejs/plugin-basic-ssl |
|---|---|---|---|
| 需要安装额外工具 | ❌ 不需要 | ✅ 需要安装 mkcert | ✅ 需要 npm 安装插件 |
| 操作复杂度 | 中等 | 简单 | 最简单 |
| 跨平台 | 仅 Windows | Win/Mac/Linux | 跨平台 |
| 浏览器信任 | 安装到根证书后信任 | 自动信任 | ❌ 始终报不安全,需手动跳过 |
| 证书有效期 | 自定义(默认 10 年) | 默认几年 | 每次启动重新生成 |
| 地址栏小锁 | ✅ 有 | ✅ 有 | ❌ 没有,显示“不安全” |
| 推荐场景 | 不想装额外工具、长期开发 | 多项目/多机器复用、长期开发 | 临时快速验证、跑通即可 |
