Question:
I searched all around and could not find a lot of information, basically I have Windows 2008 R2, I created PowerShell script to load a PFX file to certificate store of Local Machine already.
Now I need to grant permission of my app pool to read the private key of the certificate by using PowerShell.
In the old way Windows 2003, I just need to get the actual file sitting in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\
folder, but it looks like Win 2008 uses a different folder.
Anybody has some solution?
— Update my version of code —
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
function Grant-CertificatePermissions([string]$certSubject,[string]$user,[string]$permissionType,[string]$permission = $args[3]) { $getCert = Get-LocalMachineCertificate $certSubject $keypath = Get-CertificateStorePath $certHash = $getCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName $certFullPath = $keypath+$certHash $certAcl = Get-Acl -Path $certFullPath try { $accessRule=new-object System.Security.AccessControl.FileSystemAccessRule $user, $permissionType, $permission $certAcl.AddAccessRule($accessRule) } catch [System.Exception] { throw "Invalid User Id Or Permission" } Set-Acl $certFullPath $certAcl } function Get-LocalMachineCertificate([string]$subject, [string]$certificateStoreLocation, [string]$certificateStoreName) { $getCert = Get-ChildItem -Recurse Cert:\$certificateStoreLocation\$certificateStoreName | Where-Object {$_.Subject -eq $subject} if(!$getCert) { throw "Certificate Not Found" } return $getCert } function Get-CertificateStorePath { $commonCertPathStub = "\Microsoft\Crypto\RSA\MachineKeys\" $programData = $Env:ProgramData if(!$programData) { $programData = $Env:ALLUSERSPROFILE + "\Application Data" } $keypath = $programData + $commonCertPathStub return $keypath } |
In my Get-CertificateStorePath
function I get value as C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\
, after I get certificate hash, the complete file looks like C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\d82829f7770ea5d85ef978dea67f302d_4cca7190-7e9f-46d7-b180-6656fec432e2
, when I execute Get-Acl
line I have exception Cannot find path 'C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\d82829f7770ea5d85ef978dea67f302d_4cca7190-7e9f-46d7-b180-6656fec432e2' because it does not exist.
.
I browsed that folder, I indeed could not find such a file.
— Update —
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function Import-PfxCertificate ([String]$certPath,[String]$certificateStoreLocation ,[String]$certificateStoreName, $pfxPassword) { $pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2 $pfx.Import($certPath, $pfxPassword, "Exportable,PersistKeySet") $store = new-object System.Security.Cryptography.X509Certificates.X509Store($certificateStoreName,$certificateStoreLocation) $store.open("MaxAllowed") $store.add($pfx) $store.close() return $pfx } |
Answer:
2008 R2 uses C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
Via PowerShell you can see the certs available to IIS here:
1 2 |
cert:\LocalMachine\My |
You can cd into that location and look for your cert. Once you find it you can view its private key ID using:
1 2 3 |
$cert = get-item 2779B37AE3625FD8D2F9596E285C7CDC15049D87 $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName |
This will contain the long hexadecimal filename from the MachineKeys folder.
You can then change the file permissions using the Set-Acl
cmdlet.
You can also view the permissions via the Certificates MMC mmc/add snapin/certificates/computer account/local computer
and then certificates/personal/certificates/[your cert]/all tasks/manage private keys