审核重构日期:2026-10-31。Windows Server 2022;离线 Standalone Root CA + 单 Enterprise Subordinate Issuing CA + IIS HTTP CDP/AIA 同机发布。本版是可用于新环境的执行指南草案,尚未在新环境实机验收。 原始文档及截图保持不变:‣。
| 键 | 示例(按新环境修改) | 用途 |
|---|---|---|
| RootHost | ROOTCA01 | 离线主机名 |
| RootCAName | CORP-Root-CA | Root CA 名 |
| IssuingHost | ISSCA01 | 域成员主机名 |
| IssuingCAName | CORP-Issuing-CA | 企业 CA 名 |
| ADDomainFQDN | ad.example.com | AD 域 |
| PkiHost | pki.example.com | HTTP DNS 名 |
| PkiPath | pki | IIS 虚拟目录 |
| SiteName | Default Web Site | IIS 网站 |
| PublishDir | 系统 CertEnroll | 物理目录 |
| DatabaseDir | 系统 CertLog | CA 数据库 |
| BackupRoot | C:\PKI-Backup | 备份根目录 |
# 每次打开新管理员 PowerShell 5.1 会话时,首先编辑并执行本参数块
$Cfg = @{
RootHost='ROOTCA01'; RootCAName='CORP-Root-CA'
IssuingHost='ISSCA01'; IssuingCAName='CORP-Issuing-CA'
ADDomainFQDN='ad.example.com'
PkiHost='pki.example.com'; PkiPath='pki'
SiteName='Default Web Site'
PublishDir="$env:windir\System32\CertSrv\CertEnroll"
DatabaseDir="$env:windir\System32\CertLog"
BackupRoot='D:\PKI-Backup'
}
$Cfg.HttpBase = 'http://{0}/{1}/' -f $Cfg.PkiHost,$Cfg.PkiPath
$Cfg.RootConfig = '{0}\{1}' -f $Cfg.RootHost,$Cfg.RootCAName
$Cfg.IssuingConfig = '{0}\{1}' -f $Cfg.IssuingHost,$Cfg.IssuingCAName
$Cfg
通用域 DN 和域控名称从 Active Directory 动态获取,不再写死旧环境。
Import-Module ActiveDirectory
$ConfigNC=(Get-ADRootDSE).configurationNamingContext
$PKIBase="CN=Public Key Services,CN=Services,$ConfigNC"
$DC=(Get-ADDomainController -Discover).HostName
[pscustomobject]@{DC=$DC;PKIBase=$PKIBase;Domain=(Get-ADDomain).DNSRoot}
执行位置:离线 Root 主机;管理员 PowerShell。
$Sys=Get-CimInstance Win32_ComputerSystem
if ($Sys.PartOfDomain) { throw 'Root CA 不能加入域' }
if ($env:COMPUTERNAME -ine $Cfg.RootHost) { throw 'Root 主机名称与参数不符' }
if ((Get-WindowsFeature ADCS-Cert-Authority).InstallState -eq 'Installed') { throw 'CA 角色已存在,请停止新装' }
Get-ComputerInfo | Select-Object CsName,WindowsProductName,OsBuildNumber
Get-Date
$Policy=@'
[Version]
Signature="$Windows NT$"
[Certsrv_Server]
RenewalKeyLength=4096
RenewalValidityPeriod=Years
RenewalValidityPeriodUnits=20
LoadDefaultTemplates=0
[CRLDistributionPoint]
[AuthorityInformationAccess]
'@
$PolicyFile=Join-Path $env:windir 'CAPolicy.inf'
if(Test-Path $PolicyFile){throw '已有 CAPolicy.inf,请先人工审核'}
[IO.File]::WriteAllText($PolicyFile,$Policy,[Text.Encoding]::ASCII)
Get-Content $PolicyFile
Install-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools
Install-AdcsCertificationAuthority -CAType StandaloneRootCA -CACommonName $Cfg.RootCAName -CryptoProviderName 'RSA#Microsoft Software Key Storage Provider' -KeyLength 4096 -HashAlgorithmName SHA256 -ValidityPeriod Years -ValidityPeriodUnits 20 -DatabaseDirectory $Cfg.DatabaseDir -LogDirectory $Cfg.DatabaseDir
certutil -getconfig
certutil -verifykeys
审核点:Root 密钥长度 RSA 4096、SHA256、20 年自签名证书只是本方案示例策略;不照搬原文 labcasrv01、VCPLAB-Root-CA 和固定证书路径。Root 公钥证书可从 CertEnroll 列出实际文件。
合并原 Step 1.4.1—1.4.5 的重复检查,先统一修改,再重启服务和生成 CRL。下级 CA 证书的签发期限设 10 年;Root CRL 1 年 + 4 周 Overlap;禁用 Delta CRL。
certutil -setreg CA\CRLPeriod Years
certutil -setreg CA\CRLPeriodUnits 1
certutil -setreg CA\CRLDeltaPeriodUnits 0
certutil -setreg CA\CRLOverlapPeriod Weeks
certutil -setreg CA\CRLOverlapUnits 4
certutil -setreg CA\ValidityPeriod Years
certutil -setreg CA\ValidityPeriodUnits 10
$CDP='65:{0}\%3%8%9.crl\n2:{1}%3%8%9.crl' -f $Cfg.PublishDir,$Cfg.HttpBase
$AIA='1:{0}\%1_%3%4.crt\n2:{1}%1_%3%4.crt' -f $Cfg.PublishDir,$Cfg.HttpBase
certutil -setreg CA\CRLPublicationURLs $CDP
if($LASTEXITCODE){throw 'Root CDP failed'}
certutil -setreg CA\CACertPublicationURLs $AIA
if($LASTEXITCODE){throw 'Root AIA failed'}
Restart-Service CertSvc -ErrorAction Stop
certutil -crl
if($LASTEXITCODE){throw 'Root CRL failed'}
certutil -getreg CA\CRLPublicationURLs
certutil -getreg CA\CACertPublicationURLs
Get-ChildItem $Cfg.PublishDir -File | Where-Object Extension -in '.crt','.crl'
验收:查看实际 Root CRT 与 CRL 文件、Issuer、有效期、CRL Number、ThisUpdate/NextUpdate,并导出 SHA256 记录。通过受控离线介质仅传输公开的 CRT/CRL。此时完成初次 Root 备份;待签发 Issuing CA 后再次做正式封存备份(见 Step 9)。