Update/tl;dr — I've created the CertAdmin module for PowerShell Core to easily get and set certificate permissions.
I was having the same issue:
WinHttpCertCfg
seems to have been abandoned without a reasonable alternative.
- My Certificate Manager did not include a "Manage Private Keys" option as mentioned in this old MSDN blog post.
- Compiling
FindPrivateKey
is unreasonable overhead in a Windows environment.
Setting the permission for a cert involves granting the application pool the read right to the cert file.
This can be achieved using icacls.exe (the Windows Explorer security UI does not support application pools):
icacls C:\ProgramData\Microsoft\crypto\rsa\machinekeys\9876abcdeblahblahblah /grant "IIS AppPool\AppPoolName:R"
Windows stores machine keys in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
, but the names of the files are not related to the certificate. The file name for each certificate can be obtained using this PowerShell code:
ls Cert:\LocalMachine\TrustedPeople |
select Subject,@{n='FileName';e={$_.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName}} |
Format-List
(Change "TrustedPeople" if your cert is in another store.)
The name of the application pool can be obtained from the Application Pools node of the IIS Manager, or by running this PowerShell code:
Import-Module WebAdministration; ls IIS:\AppPools
This PowerShell 3 script will use Out-GridView (ogv) as a GUI pick list for the cert and the app pool, then grant the permission:
ipmo WebAdministration
$cert = (ls Cert:\LocalMachine\TrustedPeople |
ogv -OutputMode Single -Title "Select Certificate").
PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
$app = (ls IIS:\AppPools |
ogv -OutputMode Single -Title "Select App Pool").Name
icacls $env:ProgramData\Microsoft\crypto\rsa\machinekeys\$cert /grant "IIS AppPool\$($app):R"