5

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 --

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 --

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
} 
hardywang
  • 4,864
  • 11
  • 65
  • 101

3 Answers3

2

2008 R2 uses C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

Via PowerShell you can see the certs available to IIS here:

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:

$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

Andy Arismendi
  • 50,577
  • 16
  • 107
  • 124
0

If you drag and drop a certificate from User Store\Personal to Computer Store\Personal, the $getCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName value is wrong. There is no file with that value. Import the certificate again in the right store and it will work.

lvmeijer
  • 1,022
  • 13
  • 14
0

here is a complete powershell script to give permission to any user on certificate's private key.

How to Grant permission to user on Certificate private key using powershell?

Above link has script and example how to run it on powershell console window.

If you are using ApplicationPoolIdentity then you username will be 'IIS AppPool\AppPoolNameHere'

Note: You will need to use ' ' as there is a space between IIS and AppPool.

Community
  • 1
  • 1
Balpreet Patil
  • 1,644
  • 2
  • 16
  • 16