Password Decryption error

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of Scott Brown Scott Brown 5 months, 1 week ago.

  • Author
    Posts
  • #64273
    Profile photo of Scott Brown
    Scott Brown
    Participant

    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?

  • #64372
    Profile photo of Daniel Krebs
    Daniel Krebs
    Moderator

    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.

  • #64411
    Profile photo of Scott Brown
    Scott Brown
    Participant

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

    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?

You must be logged in to reply to this topic.