首页 > 解决方案 > 导入证书时缺少 PrivateKey

问题描述

我一直在使用以下 cdmlet 将 PFX 证书导入 Windows Docker 容器:

Import-PfxCertificate -FilePath $CertificatePath -CertStoreLocation $location -Password $securePassword

直到 2 天前(可能与CVE-2021-1731有关?)之前,这一切都很好,当时一些测试开始失败并出现以下错误:

System.Security.Cryptography.CryptographicException :密钥在指定状态下无效。

运行Get-ChildItem Cert:\ -Recurse | Format-List *时,我能够发现 Docker 映像的先前版本和最新版本之间的一些差异。

在以前的(工作版本)中:

 HasPrivateKey            : True
 PrivateKey               : System.Security.Cryptography.RSACryptoServiceProvider

在最新(失败版本)中:

 HasPrivateKey            : True
 PrivateKey               : 

我正在尝试在LocalMachineCurrentUser商店中安装证书。基于其他 SO 帖子,并提出了这个作为替代方案Import-PfxCertificate ...

$CertificatePath = "..." 
$securePassword = "..."

$StoreLocations=@()
$StoreLocations += 'Cert:\LocalMachine\My'
$StoreLocations += 'Cert:\LocalMachine\Root'
$StoreLocations += 'Cert:\CurrentUser\My'
$StoreLocations += 'Cert:\CurrentUser\Root'

foreach($location in $StoreLocations){
    $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
    $certificate.Import($CertificatePath, $securePassword, "PersistKeySet,MachineKeySet")

    $storeLocation = $location.Split("\")[1] # e.g. LocalMachine
    $storeName = $location.Split("\")[2] # e.g. My
    $store = New-object System.Security.Cryptography.X509Certificates.X509Store($storeName, $storeLocation)
    $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::"ReadWrite")
    $store.Add($certificate)
    $store.Close() 
}

这似乎适用于LocalMachine商店,但它失败CurrentUser(拒绝访问)。

我还尝试根据商店设置不同的值,但没有运气:

if($location -Match "CurrentUser"){
    $certificate.Import($CertificatePath, $securePassword, "PersistKeySet,UserKeySet")
}
elseif($location -Match "LocalMachine"){
    $certificate.Import($CertificatePath, $securePassword, "PersistKeySet,MachineKeySet")
}

有什么我想念的吗?

标签: c#.netpowershellcertificatex509certificate

解决方案


一切看起来都很好。HasPrivateKey返回$true,所以私钥在那里。属性为空的事实PrivateKey意味着密钥存储在密钥存储提供程序中,而不是传统的 CSP。事实上,X509Certificate2.PrivateKey属性从 .NET 4.6 开始就已经过时了。


推荐阅读