# Password Decryption error

**URL:** https://forums.powershell.org/t/password-decryption-error/8060
**Category:** DSC
**Created:** [February 15, 2017, 10:16am UTC](https://forums.powershell.org/t/password-decryption-error/8060 "2017-02-15T10:16:09Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jsbrown](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@jsbrown](https://forums.powershell.org/u/jsbrown)
#### Post date: [February 15, 2017, 10:16am UTC](https://forums.powershell.org/t/password-decryption-error/8060/1 "2017-02-15T10:16:09Z")

</div>

I’ve been trying to add a credential set to a DSC process, and run into a roadblock. The DSC server is a Windows 2012R2 system in Pull mode, and configured using WMF5.1 :

```
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
```

```
configuration DSCPullServer
{ 
    param  
    ( 
        [string[]]$NodeName = 'localhost', 
 
        [ValidateNotNullOrEmpty()] 
        [string] $certificateThumbPrint 
    ) 
 
    Import-DSCResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion 3.10.0.0
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xWebAdministration
 
 $ensureState = "present"
 $PullServerName = "FQDN of pull server"
 $RegKey = "--guid for registration--"

    Node $NodeName 
    { 
	    # this all runs on top of IIS
	    WindowsFeature WebServer
	    {
		    Ensure = $ensureState
		    Name = "Web-WebServer"
	    }

        # Next 2 items provide the IIS UI and depemd on having base IIS component installed
        WindowsFeature WebManagement
        {
            Ensure = $ensureState
            name = "Web-Mgmt-Tools"
            DependsOn = "[WindowsFeature]WebServer"
        }

        WindowsFeature IISConsole
        {
            Ensure = $ensureState
            name = "Web-Mgmt-Console"
            DependsOn = "[WindowsFeature]WebServer"
        }

	    # obviously the DSC Pull server needs the DSC-Service
        WindowsFeature DSCServiceFeature 
        { 
    	    Ensure = $ensureState 
       	    Name = 'DSC-Service'             
            DependsOn = "[WindowsFeature]WebServer"
        } 

	    #NetHTTPActivation is requires in order to start a stopped website
	    WindowsFeature NETHTTPActivation
	    { 
        	    Ensure = $ensureState
        	    Name = 'NET-HTTP-Activation'
                DependsOn = "[WindowsFeature]WebServer"
	    }
    
	    # enable32bitAppOnWin64 is required otherwise the app pool crashes on access
	    xWebAppPool DefaultAppPool
	    {
            Ensure = $ensureState
		    Name = 'PSWS'
		    State = 'Started'
		    enable32BitAppOnWin64 = $True
            DependsOn = "[WindowsFeature]WebServer"
	    } 
 
        xDscWebService DSCPullSRV
        { 
                Ensure = $ensureState
                EndpointName = 'DSCPullSRV' 
                Port = 8080 
                PhysicalPath = "$env:SystemDrive\inetpub\DSCPullSRV" 
                CertificateThumbPrint = $certificateThumbPrint          
                ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules" 
                ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
                RegistrationKeyPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService"   
                AcceptSelfSignedCertificates = $true    
                State = 'Started' 
                DependsOn = '[WindowsFeature]DSCServiceFeature'
                #UseSecurityBestPractices = $false <-- no longer a valid member
        }

        xWebsite FileRepo
        {
            Ensure = $ensureState
            Name = "Filerepo"
            State = "Started"
            PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\filerepo"
            BindingInfo = 
                            @( MSFT_xWebBindingInformation
                                 {
                                   Protocol = "HTTP"
                                   Port = 80
                                 }
                             )
            DependsOn = "[WindowsFeature]WebServer" 
        }
        
        File RegistrationKeyFile
        {
            Ensure = $ensureState
            Type = 'File'
            DestinationPath = 'C:\Program Files\WindowsPowerShell\DscService\RegistrationKeys.txt'
            Contents = $RegKey 
        }
    }
}
 
DSCPullServer -certificateThumbPrint '--fully signed cert--'
Start-DscConfiguration -path .\DSCPullServer -verbose -wait -force
```

I have a PowerShell script that is triggered from TFS Release Management that creates the MOF files for machines based on release requirements. I wont bore you with all the details of the script, but each node does contain envrypted credentials, and the resulting Configuration references a Node block:

```
Node $AllNodes.Nodename
    {
        Write-Host "Adding Local Configuration Manager config to MOF"
        #Configuration of Local Configuration Manager needed to use Encrypted Credentials to support accessing domain resources
        LocalConfigurationManager
        {
            CertificateId = $node.Thumbprint
        }
    }
```

The resulting MOF files contain encrypted credential sets such as

```
instance of MSFT_Credential as $MSFT_Credential1ref
{
Password = "-----BEGIN CMS-----\nMIIBsgYJKoZIhvcNAQcDoIIBozCCAZ8CAQAxggFa................P2OR3QmDb69\n-----END CMS-----";
 UserName = "---username---";

};
```

for each reference of the credential. All seems good on the server side.

On the Client side I have Windows 2008R2 systems, also using WMF5.1

```
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.18063
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
```

And the client is registered using this script

```
#Server to configure for
$hostname = $env:COMPUTERNAME + "." + $env:USERDNSDOMAIN

#pull server to configure against
$pullServer = "FQDN of pull server"

#Certificate CN that restricts to the certificate to be used for encryption
$encryCertCN = "CN=$($pullServer)"

#DSC Registration key - without this, the DSC server wont let you in
$regkey = "--reg key that matches pull server--"

# Get the certificate that works for encryption 
function Get-LocalEncryptionCertificateThumbprint 
{ 
    (dir Cert:\LocalMachine\Root) | %{
        # Verify the certificate is for Encryption and valid 
        If ($_.PrivateKey.KeyExchangeAlgorithm -and ($_.Issuer -eq $encryCertCN ) -and ($_.Subject -eq $encryCertCN ) )
        { 
            Write-Output "Thumbprint $($_.Thumbprint)"
            return $_.Thumbprint 
        } 
    } 
}

[DscLocalConfigurationManager()]
Configuration RegistrationMetaConfig
{
    Node localhost
    {
        Settings
        {
            ActionafterReboot="ContinueConfiguration";
            AllowModuleOverwrite = $true;
            CertificateID ='---same thumbprint as pull server--' # Get-LocalEncryptionCertificateThumbprint
            ConfigurationMode = "ApplyAndAutocorrect";
            ConfigurationModeFrequencyMins = 15;
            RebootNodeIfNeeded = $true;
            RefreshFrequencyMins = 30;
            RefreshMode = "Pull";
        }

        ConfigurationRepositoryWeb ConfigurationManager
        {
            ServerURL = "https://$($pullServer):8080/PSDSCPullServer.svc"
            RegistrationKey = $regkey  
            ConfigurationNames = @($hostname)

        }

        ReportServerWeb DSCPull
        {
            ServerURL = "https://$($pullServer):8080/PSDSCPullServer.svc"
            RegistrationKey = $regkey
        }

    }

}
        $ConfigData= @{ 
            AllNodes = @(     
                        @{  
                            # Common to all nodes
                            NodeName = "*"

                            # The path to the .cer file containing the 
                            # public key of the Encryption Certificate 
                            # used to encrypt credentials for this node 
                            CertificateFile = "C:\DSC\DscPublicKey.cer"

                            # The thumbprint of the Encryption Certificate 
                            # used to decrypt the credentials on target node 
                            Thumbprint ='--same thumbprint as on pull server--'# Get-LocalEncryptionCertificateThumbprint
                        }
                    )
                 }

Write-Host "Disabling DSC Debug"
Disable-DscDebug

Write-Host "Removing current DSC config"
Remove-DscConfigurationDocument -Stage Current, Pending, Previous -Verbose

Write-Host "Creating new DSC Config" 
RegistrationMetaConfig -ConfigurationData $ConfigData -OutputPath C:\DSC -Verbose

Write-Host "Configuring LCM to use new config"
Set-DscLocalConfigurationManager -ComputerName localhost -Path C:\DSC -Verbose -Force

Write-Host "Start DSC Configuration"
Start-DSCConfiguration -ComputerName localhost.meta -Path C:\DSC -Verbose
```

And the client registers fine. It pulls a configuration, and attempts to apply it… however - the client fails to execute the configuration

```
Status StartDate Type Mode RebootRequested NumberOfResources             
------ --------- ---- ---- --------------- -----------------             
Failure 2/15/2017 9:30:03 AM Consistency Pull False 5
```

and when I look into the event viewer I find this error in the DSC event log

```
Job {3CF0DEDD-F38B-11E6-8A11-0050569272C7} : 
MIResult: 1
Error Message: Decryption failed.
Message ID: Windows System Error 13
Error Category: 6
Error Code: 13
Error Type: WIN32
```

Now, if the certificate which was used for encryption was exported from the pull server, as a pfx, and imported into the client, (and I know it can find the cert, as I’ve seen a different error when the cert can not be found). What is causing the decryption error - and how do I go about fixing it?

---

<div class="post-metadata">

### Author: ![daniel-krebs](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/daniel-krebs/32/484_2.png) [@daniel-krebs](https://forums.powershell.org/u/daniel-krebs)
#### Post date: [February 16, 2017, 6:58am UTC](https://forums.powershell.org/t/password-decryption-error/8060/2 "2017-02-16T06:58:29Z")

</div>

Am I seeing it correctly in your client setup script that the PFX gets imported into Cert:\LocalMachine\Root which is the Trusted Root Certification Authorities folder in the MMC? If yes, try to move the certificate to Cert:\LocalMachine\My which would be the Personal folder where most server applications look for encryption/decryption certificates.

---

<div class="post-metadata">

### Author: ![jsbrown](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@jsbrown](https://forums.powershell.org/u/jsbrown)
#### Post date: [February 16, 2017, 10:27am UTC](https://forums.powershell.org/t/password-decryption-error/8060/3 "2017-02-16T10:27:18Z")

</div>

Actually, the **Get-LocalEncryptionCertificateThumbprint function** is no longer being called and the thumbprint is being provided hard coded. The Certificate **does** live in Cert:\LocalMachine\My right now. I had run into a problem where that function was returning a String for some reason (how, I dont know) and PSDesiredStateConfiguration.psm1 was throwing errors - so I just hard coded the thumbprint I needed.

Using the method described on [https://msdn.microsoft.com/en-us/powershell/dsc/securemof](https://msdn.microsoft.com/en-us/powershell/dsc/securemof) I see an error “The private key could not be acquired”

The only way I’ve been able to get to the point I am is using an internal CA signed cert using the process defined on [https://kamranicus.com/posts/2016-04-04-wmf5-powershell-dsc-generating-encryption-certificate](https://kamranicus.com/posts/2016-04-04-wmf5-powershell-dsc-generating-encryption-certificate)

More info that might point to the error:

There is also a message showing in Trace-xDscOperation that has me wondering about the Cert itself… it says:

The enveloped-data message does not contain the specified recipient

When I look this up online, there are a number of (non-DSC) posts which reference the crypto api not being able to reference the private key along with a seemingly equal number of “it cant find the cert” messages.

```
$certificates = dir Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq 'C1A7A70FEFB5EF42255BB12E4C8F83C6E71362A9' }
$certificates | FL -Property Thumbprint, PrivateKey

            $certificates | %{
                    # Verify the certificate is for Encryption and valid
                    if ( $_.PrivateKey.KeyExchangeAlgorithm )
                    {
                        if ($_.Verify ) { write-output "Cert is valid" }
                    }
                  }

Thumbprint : C1A7A70FEFB5EF42255BB12E4C8F83C6E71362A9
PrivateKey : System.Security.Cryptography.RSACryptoServiceProvider

Cert is valid
```

This would confirm that the desired thumbprint does indeed live in \LocalMachine\My

Is the Crypto Provider causing the problem?

---

<div class="post-metadata">

### Author: ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)
#### Post date: [May 16, 2024, 9:16pm UTC](https://forums.powershell.org/t/password-decryption-error/8060/4 "2024-05-16T21:16:47Z")

</div>


