如何使用 powershell 授予用户对证书私钥的权限?

Posted

技术标签:

【中文标题】如何使用 powershell 授予用户对证书私钥的权限?【英文标题】:How to Grant permission to user on Certificate private key using powershell? 【发布时间】:2017-02-24 02:34:39 【问题描述】:

证书已安装在机器上。现在我想将证书的 PrivateKey 的读取权限授予应用程序用户。

【问题讨论】:

【参考方案1】:

这就是答案。

创建了一个powershell脚本文件AddUserToCertificate.ps1

这是脚本文件的内容。

param(
    [string]$userName,
    [string]$permission,
    [string]$certStoreLocation,
    [string]$certThumbprint
);
# check if certificate is already installed
$certificateInstalled = Get-ChildItem cert:$certStoreLocation | Where thumbprint -eq $certThumbprint

# download & install only if certificate is not already installed on machine
if ($certificateInstalled -eq $null)

    $message="Certificate with thumbprint:"+$certThumbprint+" does not exist at "+$certStoreLocation
    Write-Host $message -ForegroundColor Red
    exit 1;
else

    try
    
        $rule = new-object security.accesscontrol.filesystemacces-s-rule $userName, $permission, allow
        $root = "c:\programdata\microsoft\crypto\rsa\machinekeys"
        $l = ls Cert:$certStoreLocation
        $l = $l |? $_.thumbprint -like $certThumbprint
        $l |%
            $keyname = $_.privatekey.cspkeycontainerinfo.uniquekeycontainername
            $p = [io.path]::combine($root, $keyname)
            if ([io.file]::exists($p))
            
                $acl = get-acl -path $p
                $acl.addacces-s-rule($rule)
                echo $p
                set-acl $p $acl
            
        
    
    catch 
    
        Write-Host "Caught an exception:" -ForegroundColor Red
        Write-Host "$($_.Exception)" -ForegroundColor Red
        exit 1;
        


exit $LASTEXITCODE

现在将其作为部署的一部分运行。在 powershell 控制台窗口中运行上述脚本的示例。

C:\>.\AddUserToCertificate.ps1 -userName testuser1 -permission read -certStoreLocation \LocalMachine\My -certThumbprint 1fb7603985a8a11d3e85abee194697e9784a253

此示例授予用户 testuser1 对安装在 \LocalMachine\My 中并具有指纹 1fb7603985a8a11d3e85abee194697e9784a253 的证书的读取权限

如果您使用的是 ApplicationPoolIdentity,那么您的用户名将是 'IIS AppPool\AppPoolNameHere'

注意:您需要使用 ' ',因为 IIS 和 AppPool 之间有一个空格。

【讨论】:

非常感谢,很棒的脚本。如果有人需要给予完全控制权限,那真的是 - fullcontrol 我有一台装有 PowerShell V2 的旧 Win2008 机器。我不得不在第 8 行(第一条语句)中使用 $certificateInstalled = Get-ChildItem cert:$certStoreLocation | Where $_.thumbprint -eq $certThumbprint 这不再有效。 $_.privatekey 现在返回 null。 感谢这真的节省了我的一周,我将这个答案与***.com/questions/7334216/… 结合起来,并且能够设置应用程序池来读取证书。【参考方案2】:

上述答案对我不起作用,因为 $_.privatekey 返回 null。我设法访问了私钥并为我的应用程序池分配了“读取”权限,如下所示:

param (
[string]$certStorePath  = "Cert:\LocalMachine\My",
[string]$AppPoolName,
[string]$certThumbprint
)

Import-Module WebAdministration

$certificate = Get-ChildItem $certStorePath | Where thumbprint -eq $certThumbprint

if ($certificate -eq $null)

    $message="Certificate with thumbprint:"+$certThumbprint+" does not exist at "+$certStorePath
    Write-Host $message -ForegroundColor Red
    exit 1;
else

    $rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificate)
    $fileName = $rsaCert.key.UniqueName
    $path = "$env:ALLUSERSPROFILE\Microsoft\Crypto\Keys\$fileName"
    $permissions = Get-Acl -Path $path

    $access_rule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS AppPool\$AppPoolName", 'Read', 'None', 'None', 'Allow')
    $permissions.AddAccessRule($access_rule)
    Set-Acl -Path $path -AclObject $permissions

【讨论】:

是的。接受的答案对我有用,但我运行它已经有一段时间了。有同样的问题,$_.privatekey 返回 null。谢谢你。这似乎已经解决了。 这似乎也不能正常工作了。 $rsaCert 和 $fileName 变量似乎不包含正确的信息,提取了一个 UniqueName 值,该值根本不以 $path 变量可以使用的方式存在。【参考方案3】:

作为上述脚本的替代。您可以使用 PowerShell 模块。我自己没有尝试过,但模块看起来不错。 http://get-carbon.org/index.html

这里是设置权限的命令 http://get-carbon.org/Grant-Permission.html

【讨论】:

【参考方案4】:

您可以使用证书配置工具 WinHttpCertCfg.exe 链接:https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttpcertcfg-exe--a-certificate-configuration-tool

一些代码示例:

Set privatekeyAcces to Svc-LocalAgent$@mydomain.local
*.\WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s *.d365.mydomain.com  -a "Svc-LocalAgent$@mydomain.com"*

【讨论】:

花时间向 Michael Armitage 学习 Powershell 版本。 @DonaldAirey 为什么?如果您拥有该工具并且它支持您的方案,这会简单得多。 1.因为 Powershell 是一种通用语言。 2. Powershell 将在 WinHttpCertCfg.exe 退役后很久。 3. 您的解决方案涉及设置路径以包含 WinHttpCertCfg.exe 所在的目录,并可能下载它。我不知道这个工具在我的机器上的什么位置,也没有时间去找。 $_.privatekey为空的证书上设置权限,这将抛出访问被拒绝的错误【参考方案5】:

添加 Michael Armitage 脚本,这适用于 PrivateKey 值存在和为空的情况

function setCertificatePermission 
    param($accountName, $certificate)
    if([string]::IsNullOrEmpty($certificate.PrivateKey))
    
        $rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificate)
        $fileName = $rsaCert.key.UniqueName
        $path = "$env:ALLUSERSPROFILE\Microsoft\Crypto\Keys\$fileName"
        $permissions = Get-Acl -Path $path
        $access_rule = New-Object System.Security.AccessControl.FileSystemAccessRule($accountName, 'FullControl', 'None', 'None', 'Allow')
        $permissions.AddAccessRule($access_rule)
        Set-Acl -Path $path -AclObject $permissions
     else
            $user = New-Object System.Security.Principal.NTAccount($accountName)
            $accessRule = New-Object System.Security.AccessControl.CryptoKeyAccessRule($user, 'FullControl', 'Allow')
            $store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
            $store.Open("ReadWrite")
            $rwCert = $store.Certificates | where $_.Thumbprint -eq $certificate.Thumbprint
            $csp = New-Object System.Security.Cryptography.CspParameters($rwCert.PrivateKey.CspKeyContainerInfo.ProviderType, $rwCert.PrivateKey.CspKeyContainerInfo.ProviderName, $rwCert.PrivateKey.CspKeyContainerInfo.KeyContainerName)
            $csp.Flags = "UseExistingKey","UseMachineKeyStore"
            $csp.CryptoKeySecurity = $rwCert.PrivateKey.CspKeyContainerInfo.CryptoKeySecurity
            $csp.KeyNumber = $rwCert.PrivateKey.CspKeyContainerInfo.KeyNumber
            $csp.CryptoKeySecurity.AddAccessRule($AccessRule)
            $rsa2 = New-Object System.Security.Cryptography.RSACryptoServiceProvider($csp)
            $store.close()
        

【讨论】:

以上是关于如何使用 powershell 授予用户对证书私钥的权限?的主要内容,如果未能解决你的问题,请参考以下文章

使用 powershell 导出带有私钥的证书,包括路径中的所有证书

如何禁止“应用程序请求访问受保护的项目”弹出窗口

CA证书

何时在SSL证书申请过程中生成私钥?

证书与私钥匹配

Exchange 2007 邮箱权限(没有 Powershell Cmdlet)