问题描述
我有一个PowerShell脚本,可将pfx证书安装到 LocalMachine 证书存储中.该函数如下所示:
I have a PowerShell script that installs pfx certificate into the LocalMachine certificate store. The function looks like this:
function Add-Certificate {
param
(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxPath,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxPassword
)
Write-Host "Installing certificate" -ForegroundColor Yellow
try
{
$pfxcert = new-object system.security.cryptography.x509certificates.x509certificate2
$pfxcert.Import($pfxPath, $pfxPassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", LocalMachine
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite");
$store.Add($pfxcert);
$store.Close();
return $pfxcert
}
catch
{
throw
}
}
当我打开证书管理器以验证安装时,我可以看到它已正确安装.
When I open the Certificate Manager to verify the installation I can see that it has installed correctly.
我的流程的下一步是将证书的权限分配给服务帐户.
The next step in my process is to assign permissions to the certificate to a service account.
function Set-CertificatePermission
{
param
(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$pfxThumbPrint,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$serviceAccount
)
$cert = Get-ChildItem -Path cert:\LocalMachine\My | Where-Object -FilterScript { $PSItem.ThumbPrint -eq $pfxThumbPrint; };
# Specify the user, the permissions and the permission type
$permission = "$($serviceAccount)","Read,FullControl","Allow"
$accessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission;
# Location of the machine related keys
$keyPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\";
$keyName = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName;
$keyFullPath = $keyPath + $keyName;
try
{
# Get the current acl of the private key
# This is the line that fails!
$acl = Get-Acl -Path $keyFullPath;
# Add the new ace to the acl of the private key
$acl.AddAccessRule($accessRule);
# Write back the new acl
Set-Acl -Path $keyFullPath -AclObject $acl;
}
catch
{
throw $_;
}
}
此功能失败.具体来说,该函数在尝试评估Get-Acl命令时失败,并出现以下错误: Get-Acl:找不到路径'C:\ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys \ 59f1e969a4f7e5de90224f68bc9be536_1d508f5e-0cbc-4eca- a402-3e55947faa3b'
This function fails. Specifically, this function fails when trying to evaluate the Get-Acl command, with the following error: Get-Acl : Cannot find path 'C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\59f1e969a4f7e5de90224f68bc9be536_1d508f5e-0cbc-4eca-a402-3e55947faa3b'
事实证明,密钥文件已安装到我的漫游配置文件中 C:\ Users \ MyUserName \ AppData \ Roaming \ Microsoft \ Crypto \ RSA \ S-1-5-21-1259059047-1967870486-1845911597 -155499
As it turns out the key file has been installed into my roaming profile C:\Users\MyUserName\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1259098847-1967870486-1845911597-155499
我确定添加证书"功能有问题,但是我无法弄清楚它是什么.如何强制它在C:\ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys目录中安装密钥文件?
I'm sure there is something wrong with the Add-Certificate function, but I cannot figure out what it is. How do I force it to install the key file in the C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys directory?
推荐答案
问题是当X509Certificate2
通过Import()
方法导入时,X509KeyStorageFlags
未配置为将私钥写入到计算机的私钥存储.我已经更新了该函数,以包含适当的X509KeyStorageFlags
.
The problem is the when the X509Certificate2
was getting imported via the Import()
method, the X509KeyStorageFlags
were not configured to write the private key to the computer's private key store. I've updated the function to include the appropriate X509KeyStorageFlags
.
function Add-Certificate {
[CmdletBinding()]
param
(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Path,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Password
)
Write-Verbose -Message ('Installing certificate from path: {0}' -f $Path);
try
{
# Create the certificate
$pfxcert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ErrorAction Stop;
$KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet;
Write-Verbose ('Key storage flags is: {0}' -f $KeyStorageFlags);
$pfxcert.Import($Path, $Password, $KeyStorageFlags);
# Create the X509 store and import the certificate
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList My, LocalMachine -ErrorAction Stop;
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite);
$store.Add($pfxcert);
$store.Close();
Write-Output -InputObject $pfxcert;
}
catch
{
throw $_;
}
}
这篇关于使用PowerShell设置私钥权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!