# IIS 安装 SSL 证书：导入 PFX、绑定 HTTPS 和跳转

> 在 IIS 10 上安装 SSL 证书：生成 CSR 或导入阿里云/腾讯云下载的 PFX，添加带 SNI 的 HTTPS 绑定，补全中间证书，HTTP 跳转 HTTPS，并自动续期。

Source: https://ssl.sh/zh/guides/iis-ssl-certificate/
Last updated: 2026-11-10

在 IIS 上安装 SSL 证书分四步：把 PFX 导入“本地计算机 → 个人”存储，确认中间证书已安装，添加带 SNI 的 443 端口 HTTPS 绑定，再用 URL Rewrite 把 HTTP 跳转到 HTTPS。适用于 Windows Server 2019、2022、2025 上的 IIS 10，IIS 管理器和 PowerShell 都能操作。

## 前提条件

需要服务器管理员权限，以及一张证书或申请证书的渠道。

- 安装了 Web 服务器（IIS）角色和“IIS 管理脚本和工具”功能（提供 `WebAdministration` PowerShell 模块）的 Windows Server。
- IIS 里已有在 80 端口提供服务的网站，例如 `Default Web Site`，主机名 `example.com`。
- `example.com` 的 A/AAAA 记录指向服务器，例如 `203.0.113.10`；服务器在中国大陆的需已备案；Windows 防火墙和云服务器安全组放行 TCP 443。
- CA 提供的 PFX 文件（含证书、中间证书和私钥），例如阿里云、腾讯云下载的 IIS 格式证书；或者能提交 CSR 的 CA 账户。

## 第一步：把证书导入计算机存储

IIS 只能绑定“本地计算机 → 个人”存储里带私钥的证书。已有 PFX 文件的，用管理员 PowerShell 导入：

```powershell
$pfxPassword = Read-Host -AsSecureString "PFX password"
$cert = Import-PfxCertificate -FilePath C:\certs\example.com.pfx `
  -CertStoreLocation Cert:\LocalMachine\My -Password $pfxPassword
$cert.Thumbprint
```

需要 CSR 的，在 IIS 管理器 → 服务器节点 → **服务器证书 → 创建证书申请**，通用名称填 `example.com`，选 RSA 2048 位，保存请求文件提交给 CA。CA 返回证书后，在同一台服务器上用“完成证书申请”导入，因为私钥一直留在这台机器上。在别处生成 CSR 可以用 [CSR 生成器](https://ssl.sh/zh/tools/csr-generator/)。

**只有 PEM 文件**（例如 Let's Encrypt 或云厂商的 Nginx 格式）的，先转换成 PFX，较老的 Windows 加 `-legacy`：

```bash
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out example.com.pfx
```

也可以用 [证书格式转换](https://ssl.sh/zh/tools/ssl-converter/) 在浏览器里转换。

## 第二步：确认中间证书已安装

IIS 会从本机“中级证书颁发机构”存储里查找并发送中间证书。PFX 不含中间证书时，导入 CA 提供的中间证书：

```powershell
Import-Certificate -FilePath C:\certs\intermediate.cer -CertStoreLocation Cert:\LocalMachine\CA
```

怎么找到正确的中间证书见 [安装中间证书](https://ssl.sh/zh/guides/install-intermediate-certificate/)。

## 第三步：添加 HTTPS 绑定

每个网站需要一条 443 端口的 https 绑定，勾选 SNI 后多个网站可以共用一个 IP。IIS 管理器里：选中网站 → **绑定 → 添加**，类型选 https、端口 443、主机名 `example.com`，勾选“需要服务器名称指示”，再选择证书。也可以用 PowerShell：

```powershell
Import-Module WebAdministration
New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -HostHeader "example.com" -SslFlags 1
$binding = Get-WebBinding -Name "Default Web Site" -Protocol https -HostHeader "example.com"
$binding.AddSslCertificate($cert.Thumbprint, "My")
```

## 第四步：HTTP 跳转 HTTPS

HTTP 跳转 HTTPS 靠微软的 IIS URL Rewrite（URL 重写）模块实现。先安装这个模块，再在网站的 `web.config` 里加规则：

```xml
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="HTTP to HTTPS" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="^OFF$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

保留 80 端口的绑定，跳转才有地方响应；不要勾选**要求 SSL**，它会让 HTTP 访问返回 403 而不是跳转。

## 验证

配置正确时，`example.com` 返回 CA 签发的证书，证书链完整，HTTP 请求永久跳转到 HTTPS。用 [SSL 证书检查](https://ssl.sh/zh/tools/ssl-checker/) 检查网站，或在终端运行：

```bash
curl ssl.sh/example.com
```

在服务器上确认绑定和 HTTP.sys 使用的证书：

```powershell
Get-WebBinding -Name "Default Web Site"
netsh http show sslcert hostnameport=example.com:443
```

## 自动续期

IIS 本身不会续期证书。用商业证书或云厂商免费证书时，每次到期前都要重复第一步和第三步；2026 年 3 月 15 日起公网证书最长 200 天（2027 年 3 月 15 日起 100 天，2029 年 3 月 15 日起 47 天），手动续期已经跟不上。可选方案：

- 用 [win-acme](https://ssl.sh/zh/guides/win-acme/) 申请 Let's Encrypt 证书，通过计划任务自动更新 IIS 绑定。
- CA 支持 ACME 的（很多商业 CA 支持，需要 EAB 外部账户绑定），让 win-acme 对接该 CA 的 ACME 地址。

无论哪种方式，都把网站加到 [ssl.sh 监控](https://ssl.sh/zh/monitor/)（开发中），绑定的证书快过期时能及时发现。

## 常见问题排查

- **指定的登录会话不存在（A specified logon session does not exist）**：私钥缺失或在错误的存储里，把 PFX 重新导入“本地计算机 → 个人”。
- **完成证书申请失败，或证书在列表里消失**：CSR 是在另一台服务器上生成的，私钥不在这里，从原服务器导出 PFX 或重新生成 CSR。
- **浏览器正常，其他客户端报证书链不受信任**：缺少中间证书，见 [缺少中间证书](https://ssl.sh/zh/errors/missing-intermediate-certificate/)。
- **ERR_SSL_VERSION_OR_CIPHER_MISMATCH**：没有与请求域名匹配的绑定，或 Schannel 与客户端没有共同支持的协议，见 [ERR_SSL_VERSION_OR_CIPHER_MISMATCH](https://ssl.sh/zh/errors/err-ssl-version-or-cipher-mismatch/)。
- **证书域名不匹配**：绑定的主机名或证书 SAN 不包含访问的域名，见 [NET::ERR_CERT_COMMON_NAME_INVALID](https://ssl.sh/zh/errors/net-err-cert-common-name-invalid/)。
