我正在尝试导入带有私钥的证书,尽管我的脚本正在"工作",但它缺少一些我似乎无法弄清楚的东西。
我有一个与 KeyVault 通信并使用此证书进行授权的应用程序。我有该证书的密码,当我手动安装PFX
并分配NETWORK SERVICE
帐户权限时,这工作正常。但是,使用以下PowerShell,我收到错误Keyset does not exist
。当我在证书管理器下检查时,一切似乎都很正常。显然,UI正在做一些不同的事情。有什么想法吗?
编辑当我手动添加NETWORK SERVICE
帐户时,这工作正常。当我执行脚本时,PowerShell 正在管理模式下运行,所以也许它有些奇怪?
脚本
cls
$certName = "certname.pfx"
$path = "C:Certificates$certName"
$serviceAccount = 'NETWORK SERVICE'
$permissionType = 'Read'
$password = 'somepassword'
try {
# Import the certificate maintaining the private key format
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($path, $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
# Add the cert to personal store location
$store = Get-Item Cert:LocalMachineMy
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite")
$store.Add($cert)
$store.Close()
# Get SecurityIdentifier value from current username
$currentUser = New-Object System.Security.Principal.NTAccount($env:USERNAME)
$strSID = $currentUser.Translate([System.Security.Principal.SecurityIdentifier])
$path = "$env:USERPROFILEAppDataRoamingMicrosoftCryptoRSA$($strSID.Value)$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$acl = Get-Acl $path
$rule = New-Object Security.AccessControl.FileSystemAccessRule $serviceAccount, 'FullControl', Allow
$acl.AddAccessRule($rule)
Set-Acl $path $acl
Write-Host "Cert installed, press any key to continue" -ForegroundColor Green
Read-Host
}
catch {
Write-Error -Message $_
}
答对于遇到与我相同问题的其他人,只需提供多个存储标志:
$flags = @([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"MachineKeySet", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($path, $password, $flags)
希望同时使用 PersistKeySet
和 MachineKeySet
导入证书。 看看你在这里做事的方式,你有
- 在不指定用户与计算机密钥集的情况下打开 PFX
- 将其添加到
LocalMachine
存储区。 - 在当前用户的 SID 下查找密钥文件。
Windows 证书存储 AFAIK 不会写下哪个用户拥有密钥,只是此证书与"用户密钥 {id}"配对。 因此,它必须是计算机(共享(密钥存储。
"密钥集不存在"是因为网络服务用户的密钥库中没有使用该 ID 命名的密钥。
因此,区别可能在于 UI 断言MachineKeySet
(等效(,因为它知道您正在导入到本地计算机存储中。