使用PowerShell进行Windows证书管理

如果你是Windows系统管理员,你可能被迫与Windows证书打交道。在Windows中处理证书通常是系统管理员必须承担的额外责任之一。使用Windows证书管理器作为工具,你可以完成这项任务!

证书通常很复杂且难以理解,但在这篇文章中,你将有机会发现在Windows中证书并不那么可怕!

本文将主要介绍在Windows中处理证书的相关内容。如果你想了解证书在一般情况下是如何工作的,请查阅本文的伴随X.509证书教程文章。

理解证书存储

在Windows证书管理器中,所有证书存在于称为证书存储的逻辑存储位置。证书存储是Windows保存当前安装的所有证书的“桶”,而且一个证书可能存在于多个存储中。

不幸的是,证书存储并不是最直观的概念。在下文中,你将了解如何区分这些存储以及如何操作它们。

每个存储位于Windows注册表和文件系统中。有关详细信息,请参阅下表。在处理存储中的证书时,你是在与逻辑存储进行交互;而不是直接修改注册表或文件系统。这种简化的方式让你可以处理单个对象,而Windows会负责在磁盘上如何表示该对象。

您有时会看到证书存储被称为物理或逻辑存储。物理存储指实际的文件系统或注册表位置,存储着注册表键和/或文件。逻辑存储是动态引用,引用一个或多个物理存储。对于大多数常见用例,逻辑存储比物理存储更容易使用。

Windows将证书存储在两个不同的区域——用户和计算机上下文中。证书被放置在这两个上下文之一,取决于证书是应该被单个用户、多个用户还是计算机本身使用。在本文的其余部分中,用户和计算机上下文中的证书将非正式地称为用户证书和计算机证书。

用户证书

如果您打算让证书被单个用户使用,则在Windows证书管理器中使用用户证书存储是理想的。这是基于证书的认证过程的常见用例,例如有线IEEE 802.1x。

用户证书位于当前用户的配置文件中,并且在该用户的上下文中仅被逻辑映射。用户证书被“映射”,在同一系统上即使对于每个用户也是唯一的。

计算机证书

如果证书将由计算机上的所有用户或系统进程使用,应将其放置在计算机上下文中的存储中。例如,如果证书将在Web服务器上用于为所有客户端加密通信,则将证书放置在计算机上下文中的存储中将是理想的。

您会注意到计算机的证书存储在逻辑上映射到所有用户上下文。这允许计算机证书存储中的证书被所有用户使用,具体取决于为私钥配置的权限。

有关私钥的更多信息,请查阅文章X.509证书教程:系统管理员指南。

计算机证书位于本地计算机注册表蜂窝和Program Data文件夹中。用户证书位于当前用户注册表蜂窝和App Data文件夹中。下面您可以看到注册表和文件系统中每种存储类型的位置分布。

Context Registry Path Explanation
User HKCU:\SOFTWARE\Microsoft\SystemCertificates\ Physical store for user-specific public keys
User HKCU:\SOFTWARE\Policies\Microsoft\SystemCertificates\ Physical store for user-specific public keys installed by Active Directory (AD) Group Policy Objects (GPOs)
Computer HKLM:\SOFTWARE\Microsoft\SystemCertificates\ Physical store for machine-wide public keys
Computer HKLM:\SOFTWARE\Microsoft\Cryptography\Services\ Physical store for keys associated with a specific service
Computer HKLM:\SOFTWARE\Policies\Microsoft\SystemCertificates\ Physical store for machine-wide public keys installed by GPOs
Computer HKLM:\SOFTWARE\Microsoft\EnterpriseCertificates\ Physical store for machine-wide public keys installed by the Enterprise PKI Containers within an AD domain
Context File Location Explanation
User $env:APPDATA\Microsoft\SystemCertificates\ Physical store for user-specific public keys and pointers to private keys
User $env:APPDATA\Microsoft\Crypto\ Physical store for user-specific private key containers
Computer $env:ProgramData\Microsoft\Crypto\ Physical store for machine-wide private key containers

先决条件

在本文的其余部分,您将找到多个示例,显示与Windows证书存储的交互。要复制这些示例,请确保您满足以下先决条件:

  • Windows Vista、Windows Server 2008或更新的操作系统。所示示例使用Windows 10企业版版本1903。
  • 熟悉PowerShell。虽然不是必需的,但这将是引用适当的情况下证书的语言。所示示例均已使用Windows PowerShell 5.1创建。
  • 你将不需要安装任何特定证书来跟随操作,但使用自签名证书是有益的。

在Windows中管理证书

在Windows中,有三种主要的管理证书的方式:

  • 证书Microsoft管理控制台(MMC)插件(certmgr.msc
  • PowerShell
  • certutil命令行工具

在这篇文章中,您将学习如何通过证书MMC插件和PowerShell管理证书。如果您想了解更多关于如何使用certutil的信息,请查阅Microsoft Docs

PowerShell与Windows安全证书管理器对比

由于在Windows中可以通过几种不同的方式管理证书,您应该选择哪一种?是选择GUI(MMC)还是使用PowerShell进行命令行操作?

注意:本文对Windows 7证书管理器和Windows 10证书管理器MMC插件都适用。

首先,考虑证书的生命周期。如果您只打算安装或删除单个证书一次,请考虑使用MMC。但如果您要管理多个证书或发现自己一遍又一遍地执行相同的任务,可能使用命令行是更好的选择。即使您不知道如何编写PowerShell脚本,如果您有许多不同的证书要管理,学习一下也是值得的。

让我们首先看一下如何使用证书管理器和PowerShell在Windows上查找已安装的证书。

使用Windows证书管理器(certmgr.msc

要使用MMC查看证书,请打开证书管理器,打开开始菜单,然后键入certmgr.msc。这将打开Windows证书MMC。此初始视图将提供左窗口中显示的所有逻辑存储的概述。

您可以在下面的截图中看到选择了受信任的根证书颁发机构逻辑存储。

Trusted Root Certification Authorities store

查看物理存储

默认情况下,Windows证书管理器不会显示实际的物理存储。要显示存储,单击查看,然后单击选项。然后,您将看到选择显示物理证书存储的选项。启用此选项可更容易地识别Windows中的特定路径。

Figure 2 – The Certificates MMC View Options with Physical certificate stores selected.

现在,您可以看到在先前显示的受信任的根证书颁发机构逻辑存储下显示了其他容器。证书仍然相对于其逻辑存储分组,但现在您可以看到物理存储“注册表”

Inspecting the physical cert stores

在Windows证书管理器中检查属性

使用MMC查看证书时,您可以看到证书的许多属性。例如,您可能希望选择特定的证书。

最简单的方法是参考证书的序列号Thumbprint扩展值。如果证书由证书颁发机构(CA)签发,那么在签发时会有一个序列号。Thumbprint 是每次查看证书时计算的。

您可以通过在 MMC 中打开证书来查看一些属性,就像下面所示的那样。

Inspecting a Windows certificate

要指出的一个重要特点是嵌入式私钥。Windows 中的证书也可以有相应的私钥。这些私钥以加密文件的形式存储在相应的物理存储中。

要快速区分具有和不具有相应私钥的证书,请查看证书图标。在 Windows 证书管理器中,如果图标看起来只是一个带有丝带的纸张,那么就没有相应的私钥。如果证书有私钥,您将在 MMC 图标中看到一个键,并且在打开证书时的常规选项卡底部将看到一个键。

Certificate without an embedded private key

使用 PowerShell

与 MMC 一样,您也可以使用 PowerShell 查看和管理证书。让我们首先检查物理存储中的证书(注册表和文件系统)。

通过物理存储

使用 Get-ChildItem PowerShell 命令,您可以枚举父级HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates\注册表键路径中的所有键和值。

以下命令将枚举当前登录用户在中间证书颁发机构逻辑存储中的所有证书。

Get-ChildItem -Path HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates\

你在下面看到的注册表中的每个条目都对应于受信任 CA 的证书的指纹及其在相应属性中的证书。你可以看到这个操作的示例输出。

Results of the installed certificates from the example commands, limited to the first 5 entries.

另一个常见的存储是个人存储。该存储中的证书位于文件系统而不是注册表中。在以下命令中,我们将展示这些不同的物理路径及其目的。

通过下面的命令返回的目录中的每个文件对应于安装在个人当前用户存储中的证书。

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Certificates\

在下面的命令中返回的每个文件都是由密钥存储提供程序(KSP)创建的私钥对象的引用。文件名对应于证书的主题密钥标识符。你安装的每个私钥都会有一个相应的文件。

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Keys\

通过下面的命令返回的目录中的每个文件都是由 KSP 创建的加密私钥的唯一容器。文件名和证书之间没有直接的关系,但该文件是前面命令中指针的目标。

Get-ChildItem -Path $env:APPDATA\Microsoft\Crypto\Keys

按逻辑存储

由于在其物理路径中使用证书并不常见,您将在其余示例中使用逻辑存储。

PowerShell 可以使用 Cert: PSDrive 访问 Windows 逻辑存储。 Cert: PSDrive 将证书映射到物理存储,类似于 MMC 的工作方式。

不幸的是,MMC 和 Cert PSDrive 并不以相同的方式标记逻辑存储。在下面,您可以看到 MMC 和 Cert PSDrive 中常见存储的对比表格。

Cert: Certificates MMC
My Personal
Remote Desktop Remote Desktop
Root Trusted Root Certification Authorities
CA Intermediate Certification Authorities
AuthRoot Third-Party Root Certification Authorities
TrustedPublisher Trusted Publishers
Trust Enterprise Trust
UserDS Active Directory User Object
选择证书

在处理证书时,您需要一种方法来筛选和选择证书以执行特定操作。大多数情况下,您将根据特定扩展的值来筛选和选择证书。

在以下示例中,您需要首先列出根 CA 存储中安装的所有证书。

Get-ChildItem -Path Cert:\CurrentUser\Root\

返回的对象将是您可以在以下示例中使用的证书对象。

常见扩展已作为证书对象的属性提供。在下面的示例中,您使用 Get-Member 列出返回对象的所有属性。

Get-ChildItem -Path Cert:\CurrentUser\Root\ | Get-Member -MemberType Properties
Figure 9 – The properties available for the returned certificate objects.

如图9所示,一些扩展(例如颁发者)对于查找您要查找的证书非常有帮助。扩展提供有关证书的信息,例如它是由谁颁发的,可以用于什么以及对它的任何限制。

在更复杂的使用情境中,您可能希望按其他扩展名查找证书,比如使用的证书模板。困难之处在于这些扩展的值返回为整数数组。这些整数对应于ASN.1编码的内容。

对象上可用的现有ScriptProperties显示了与这些内容进行交互的示例。在下面的命令中,您将手动提取密钥用途以查看这种关系。

((Get-ChildItem -Path Cert:\CurrentUser\Root\ | select -First 1).Extensions | Where-Object {$_.Oid.FriendlyName -eq "Key Usage"}).format($true)

在上述命令中引入的新部分是format方法,它执行ASN.1解码。您传递一个布尔值(例如$true)来标识我们是否希望返回的对象是单行还是多行。

您将使用图7中证书的Thumbprint值在下面的命令中。Thumbprint值被设置为PowerShell变量,并用于在下面的命令中选择特定的证书。

$thumb = "cdd4eeae6000ac7f40c3802c171e30148030c072"
Get-ChildItem -Path Cert:\CurrentUser\Root\ | Where-Object {$_.Thumbprint -eq $thumb}

使用PowerShell创建自签名证书

PowerShell可以使用New-SelfSignedCertificate cmdlet创建自签名证书。自签名证书对于测试很有用,因为它们允许您生成公钥和私钥对,而无需使用CA。

现在,让我们在“当前用户”和“本地计算机”存储中创建一个自签名证书,以便在接下来的示例中使用。

在下面的示例中,PowerShell正在生成公钥和私钥对、自签名证书,并将它们全部安装到适当的证书存储中。

PS51> New-SelfSignedCertificate -Subject 'User-Test' -CertStoreLocation 'Cert:\CurrentUser\My'
PS51> New-SelfSignedCertificate -Subject 'Computer-Test' -CertStoreLocation 'Cert:\LocalMachine\My'

在生产服务中不鼓励使用自签名证书,因为所有基于信任的机制都不存在。

导入/导出证书

公钥加密基于公钥广泛可访问的基本原理。考虑到这一原则,您需要标准的方法有效地共享证书。同样重要的是保护私钥的安全性。将私钥存储在无法访问的介质中,或与灾难恢复材料一起存储是某些私钥的常见做法。

这两者都需要以标准格式存储这些加密对象的方法。导出提供了执行存储这些对象并确保它们使用广泛接受的标准文件格式的功能。导入允许您将加密对象引入Windows操作系统。

使用Windows证书管理器(certmgr.msc

从MMC导出证书相对直截了当。要导出不带私钥的证书,请在MMC中单击证书,单击所有任务菜单,然后单击导出

在导出过程中,将要求您选择如下所示的文件格式。最常见的选项是DERBase-64编码

Figure 10 – Exporting a certificate with no private key or one that is marked as not exportable.

导出私钥

要导出带有关联私钥的证书,您必须满足两个条件:已登录的帐户必须具有对私钥的权限(仅适用于计算机证书),并且私钥必须标记为可导出。

要验证本地计算机的私钥权限,您可以选择带有私钥的证书,从证书 MMC 中选择 所有任务,然后选择 管理私钥。打开的对话框将显示私钥的访问控制条目。

The Basic Security Property Page for the private keys of a certificate with the Subject of ServerName.

当满足这两个或三个先决条件时,您可以选择一个证书,单击 所有任务,然后像处理只有公钥的证书一样单击 导出。导出后,现在应该有选择 是,导出私钥 的选项,如下所示。

Certificate Export Wizard with exportable private key.

在 Windows 中导出私钥时,您只能将文件保存为 PFX。这些文件类型和编码格式在此帖子中有详细说明。

对于导出向导中显示的剩余设置,您可以使用默认设置。下表是每个设置的快速概述。

Setting Description
Including all certificates in the certification path if possible Helps with portability of certificate issuers, and includes all pertinent public keys in the PFX
Delete the private key if the export is successful Removes the private key from the file and has few common use cases, but one example is to test access to private keys
Export all extended properties Will include any extensions within the current certificate, these relate to the certificates [specific settings]() for Windows interfaces
Enable certificate privacy Normally only the private key will be encrypted in the exported PFX file, this setting encrypts the entire contents of the PFX file
Group or user names You can use a group or user security principal from Active Directory for encrypting the contents of the PFX file, but a password is the most portable option across legacy systems or computers not joined to the same domain

导入证书

导入功能对所有支持的证书文件类型都是相同的。唯一的区别是如果文件包含私钥,则可以“标记此密钥为可导出”,您将在下文中详细了解。Windows 将利用证书导入向导。

Figure 12 – Certificate Import Wizard with a PFX file.

当您使用 PFX 的证书导入向导时,您需要提供用于加密私钥的密码。以下是导入选项的另一个简要回顾。

Setting Description
Enable strong private key protection Requires a password for each access of a private key, be cautious of newer functions as they will not be supported in all software
Mark this key as exportable You should try to avoid using this setting on any end system, private keys should be treated similarly to storing passwords
Protect private key using [virtualization-based security] The setting provides more security functionality for protecting private keys from advanced malware attacks
Include all extended properties Relates to the same Windows-specific settings discussed as with exporting

PowerShell代码签名证书是强私钥保护的一个很好的用例。

证书的自动放置是需要谨慎对待的事项。手动选择证书存储库很可能会获得最佳结果。

使用PowerShell

现在,使用PowerShell导出你之前创建的自签名证书之一。在示例中,使用了当前用户,但你也可以选择其他用户。

在下面的示例中,你正在选择当前用户个人逻辑存储中的一个自签名证书,意味着颁发者与主题匹配。

$certificate = Get-Item (Get-ChildItem -Path Cert:\CurrentUser\My\ | Where-Object {$_.Subject -eq $_.Issuer}).PSPath

现在,你已经选择了一个证书,可以使用Export-Certificate命令保存一个使用以下命令的DER编码文件。

Export-Certificate -FilePath $env:USERPROFILE\Desktop\certificate.cer -Cert $certificate

现在让我们来看看如何导出私钥。在下面的示例中,你正在验证你选择的证书是否有私钥,如果返回值不为true,则Get-Item命令可能选择了错误的证书。

$certificate.HasPrivateKey

在下面,你将设置一个用于加密私钥的密码。然后,将选定的证书导出到PFX文件,并使用先前输入的密码对文件进行加密。

$pfxPassword = "ComplexPassword!" | ConvertTo-SecureString -AsPlainText -Force
Export-PfxCertificate -FilePath $env:USERPROFILE\Desktop\certificate.pfx -Password $pfxPassword -Cert $certificate

与导出类似,导入证书和导入PFX文件有两个命令。

下面的Import-Certificate命令将导入您之前导出到当前用户个人存储区的DER编码文件。

Import-Certificate -FilePath $env:USERPROFILE\Desktop\certificate.cer -CertStoreLocation Cert:\CurrentUser\My

假设您还想安装该证书的私钥。

$pfxPassword = "ComplexPassword!" | ConvertTo-SecureString -AsPlainText -Force
Import-PfxCertificate -Exportable -Password $pfxPassword -CertStoreLocation Cert:\CurrentUser\My -FilePath $env:USERPROFILE\Desktop\certificate.pfx

请记住,密码需要是一个Secure String。此外,如果您要导入到本地计算机存储区(例如Cert:\LocalMachine\),则需要从提升的管理员提示符中运行该命令。

在上面的示例中,您还可以使用该命令的Exportable参数,将私钥标记为将来可导出的状态。默认情况下,私钥是不可导出的。可导出的私钥是另一个安全考虑因素,并且需要进一步关注如何保护它们。

在Windows中,还有许多其他与证书相关的操作,因此您应该进行更多探索。

使用PowerShell删除证书

在删除证书时,您需要记住没有回收站。一旦您删除了证书,它就会消失。这意味着确认您正在删除的是正确的证书至关重要,方法是验证唯一标识符,如序列号或Thumbprint扩展值。

与上述类似,在下面的命令中,我们从当前用户个人存储区选择一个自签名证书。

$certificate = Get-Item (Get-ChildItem -Path Cert:\CurrentUser\My\ | Where-Object {$_.Subject -eq $_.Issuer}).PSPath

您可以看到所选证书的Thumbprint、序列号和主题属性,以确保您选择的是您打算选择的证书。

$certificate.Thumbprint
$certificate.SerialNumber
$certificate.Subject

请确认您已选择要删除的正确证书。

以下命令将删除所有选定的证书对象,请谨慎使用。通过将$certificate对象传递到下面命令中的Remove-Item cmdlet,您将删除所有证书内容而不会收到任何验证提示。

$certificate | Remove-Item

摘要

在本文中,您已经学习了如何在Windows中使用证书以及一些处理证书时可以使用的工具。关于这个主题还有很多可以探索的内容,包括如何将安装的证书与特定服务关联,甚至如何通过部署自己的证书颁发机构(CA)来实现私有公钥基础设施(PKI)。

进一步阅读

Source:
https://adamtheautomator.com/windows-certificate-manager/