Joseph Michael Pesch
VP Programming

WCF Service X.509 Certificate CryptographicException: Keyset does not exist or Access is denied

by 3. August 2012 17:14

When I tried running my WCF service I received a System.Security.Cryptography.CryptographicException: Keyset does not exist or Access is denied. In my case the issue was that the user my IIS application pool was running under did not have access to the private key. There are a couple ways to grant the user access and make the X.509 certificate accessible to WCF.

Option 1: Grant read access to the file that contains the private key to the account that WCF is running under, using a tool such as cacls.exe. See this link for full topic: http://msdn.microsoft.com/en-us/library/aa702621.aspx

The following code example edits (/E) the access control list (ACL) for the specified file to grant (/G) the NETWORK SERVICE account read (:R) access to the file.

cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\8aeda5eb81555f14f8f9960745b5a40d_38f7de48-5ee9-452d-8a5a-92789d7110b1" /E /G "NETWORK SERVICE":R

Option 2: Use the Microsoft Management Console (MMC)
1) Start > Run > MMC
2) File > Add/Remove Snap-in > Certificates, Add, Computer Account, Local
3) Open > Certificates > Personal > Certificates
4) Right Click Certificate > All Tasks > Manage Private Keys
5) Add Network Service (or whatever login the application pool is running under) with Read access

Option 3: Use Windows HTTP Services Certificate Configuration Tool (WinHttpCertCfg.exe) located here: http://www.microsoft.com/en-us/download/details.aspx?id=19801
"C:\Program Files (x86)\Windows Resource Kits\Tools\winhttpcertcfg" -g -c LOCAL_MACHINE\My -s MyCertificate -a DefaultAppPool

The installation folder of this program contains an HTML instruction file on the command line parameters.

Tags:

WCF Service X.509 Certificate CryptographicException: Keyset does not exist or Access is denied

by 3. August 2012 15:19

When I tried running my WCF service is received a System.Security.Cryptography.CryptographicException: Keyset does not exist or Access is denied.  In my case the issue was that the user my IIS application pool was running under did not have access to the private key.  There are a couple ways to grant the user access and make the X.509 certificate accessible to WCF.

Option 1: Grant read access to the file that contains the private key to the account that WCF is running under, using a tool such as cacls.exe.  See this link for full topic: http://msdn.microsoft.com/en-us/library/aa702621.aspx
The following code example edits (/E) the access control list (ACL) for the specified file to grant (/G) the NETWORK SERVICE account read (:R) access to the file.
cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\8aeda5eb81555f14f8f9960745b5a40d_38f7de48-5ee9-452d-8a5a-92789d7110b1" /E /G "NETWORK SERVICE":R

Option 2:  Use the Microsoft Management Console (MMC)
1) Start > Run > MMC
2) File > Add/Remove Snap-in > Certificates, Add, Computer Account, Local
3) Open > Certificates > Personal > Certificates
4) Right Click Certificate > All Tasks > Manage Private Keys
5) Add Network Service (or whatever login the application pool is running under) with Read access

Option 3:  Use Windows HTTP Services Certificate Configuration Tool (WinHttpCertCfg.exe) located here: http://www.microsoft.com/en-us/download/details.aspx?id=19801
Typical installation path: C:\Program Files (x86)\Windows Resource Kits\Tools\
This is another command line option and the installation folder contains an HTML instruction file on the command line parameters.

Tags:

Sharepoint Powershell Script to Remove Missing Feature References from Sharepoint Site Content Configuration

by 2. August 2012 11:55

Our Sharepoint 2010 Central Administration portal Health Analyzer shows a "Missing server side dependencies." entry.  When clicking into the details of that entry we see the error shown below:

[MissingFeature] Database [WSS_CONTENT_MySite] has reference(s) to a missing feature: Id = [00000000-0000-0000-0000-000000000000]. The feature with Id 00000000-0000-0000-0000-000000000000 is referenced in the database [WSS_CONTENT_MySite], but is not installed on the current farm

Below is code to find and or delete the reference to the missing feature.  Thanks to Phil Childs blog entry: http://get-spscripts.com/2011/06/removing-features-from-content-database.html for providing the powershell script.

Code (note remove the -ReportOnly parameter to actually delete the reference):

function Remove-SPFeatureFromContentDB($ContentDb, $FeatureId, [switch]$ReportOnly)
{
    $db = Get-SPDatabase | where { $_.Name -eq $ContentDb }
    [bool]$report = $false
    if ($ReportOnly) { $report = $true }
    
    $db.Sites | ForEach-Object {
        
        Remove-SPFeature -obj $_ -objName "site collection" -featId $FeatureId -report $report
                
        $_ | Get-SPWeb -Limit all | ForEach-Object {
            
            Remove-SPFeature -obj $_ -objName "site" -featId $FeatureId -report $report
        }
    }
}

function Remove-SPFeature($obj, $objName, $featId, [bool]$report)
{
    $feature = $obj.Features[$featId]
    
    if ($feature -ne $null) {
        if ($report) {
            write-host "Feature found in" $objName ":" $obj.Url -foregroundcolor Red
        }
        else
        {
            try {
                $obj.Features.Remove($feature.DefinitionId, $true)
                write-host "Feature successfully removed from" $objName ":" $obj.Url -foregroundcolor Red
            }
            catch {
                write-host "There has been an error trying to remove the feature:" $_
            }
        }
    }
    else {
        #write-host "Feature ID specified does not exist in" $objName ":" $obj.Url
    }
}

Remove-SPFeatureFromContentDB -ContentDB "WSS_CONTENT_MySite" -FeatureId "00000000-0000-0000-0000-000000000000" -ReportOnly

Tags: