Сертификат уже установлен на машине. Теперь я хочу дать разрешение на чтение PrivateKey сертификата пользователю приложения.
Как предоставить разрешение пользователю на закрытый ключ сертификата с помощью powershell?
Ответы (5)
Вот ответ.
Создан файл сценария 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.filesystemaccessrule $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.addaccessrule($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 есть пробел.
$certificateInstalled = Get-ChildItem cert:$certStoreLocation | Where {$_.thumbprint -eq $certThumbprint}
в строке 8 (первый оператор)
- person Tony; 09.05.2018
Приведенный выше ответ не сработал для меня, так как $_.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
}
В качестве альтернативы приведенному выше сценарию. Вы можете использовать модуль PowerShell. Сам не пробовал, но модуль выглядит хорошо. http://get-carbon.org/index.html
Вот команда для установки разрешений http://get-carbon.org/Grant-Permission.html а>
Вы можете использовать WinHttpCertCfg.exe, средство настройки сертификата. Ссылка: https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttpcertcfg-exe--a-certificate-configuration-tool
Пример кода:
Set privatekeyAcces to [email protected]
*.\WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s *.d365.mydomain.com -a "[email protected]"*
$_.privatekey
равно нулю, это вызовет ошибку отказано в доступе
- person Ankit Patel; 23.06.2020
Добавление сценария Майкла Армитиджа. Это будет работать как для случаев, когда значение 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()
}
}