Page 1 of 5

GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 10:59 am
by jsira2003@yahoo.com
The following function works well in the powershell ise. I supply the encrypted file. I get an a userkey array returned. Works like a champ. If I work this within my application built by powershell studio the following line returns nothing:

$Secure2 = $aline | ConvertTo-SecureString -Key ($key)

I have not included the byte array for the keys intentionally. I have validated this function at everypoint within it observing the values of the variables and the arrays. The point of failure is the line above. The file gets read it correctly. The line gets passed in correctly to the convertto-securestring but returns nothing in the powershell studio app but works great in ps ise.
At the end of the function I have an array strings I can use in the global variable.

Function DecryptUserKey([string]$file)
{
#use decryption key for program/version
#use appropriate key for program and version

#$key = $global:programA
$key = $global:ProgramB

#read back decrypted from file
$global:userKey = @()
$alllines = Get-Content $file

foreach ($aline in $alllines)
{

$Secure2 = $aline | ConvertTo-SecureString -Key ($key)
$line = (New-Object System.Management.Automation.PSCredential 'N/A', Secure2).GetNetworkCredential().Password
$global:userKey += $line


}

}

Any ideas here? Any suggestions? What did I do incorrectly? Is there an alternate encryption decryption method you can recommend?

Thanks in advance,
John

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 11:28 am
by jvierra
Try testing for errors and report them. Exceptions in a form can be lost.

Code: Select all

Function DecryptUserKey([string]$file){
    
    $ErrorActionPreference = 'Stop'
    Try{
        #use decryption key for program/version
        #use appropriate key for program and version
        
        #$key = $global:programA
        $key = $global:ProgramB
        
        #read back decrypted from file
        $global:userKey = @()
        $alllines = Get-Content $file
        
        foreach ($aline in $alllines) {
            
            $Secure2 = $aline | ConvertTo-SecureString -Key $key
            $line = (New-Object System.Management.Automation.PSCredential 'N/A', Secure2).GetNetworkCredential().Password
            $global:userKey += $line
            
            
        }
    }
    Catch{
        [System.Windows.Forms.MessageBox]::Show($_)
    }
    
}

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 11:45 am
by jvierra
Actually there are some issue with your code. The following works correctly:

Code: Select all

Function DecryptUserKey([string]$file){
    
    $ErrorActionPreference = 'Stop'
    Try{
        #use decryption key for program/version
        #use appropriate key for program and version
        
        $key = $global:programA
        $key = $global:ProgramB
        
        $global:userKey = @()
        
        #read back decrypted from file
        $alllines = Get-Content $file
        foreach ($aline in $alllines) {
            $Secure2 = $aline | ConvertTo-SecureString -Key $key
            $global:userKey += ([System.Management.Automation.PSCredential]::New('N/A', $Secure2)).GetNetworkCredential().Password
        }
        
    }
    Catch{
        [System.Windows.Forms.MessageBox]::Show($_)
    }
    
}

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 1:29 pm
by jsira2003@yahoo.com
I take it the erroractionpreference stop will stop function if an error is encounter after reporting message.

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 1:56 pm
by jsira2003@yahoo.com
I now have an error message. I am not sure why I have it but I think I'm going to learn more today. The message is: padding is invalid and cannot be removed

At this point I am not sure where to adjust it. From what I read the padding should be the same on both the encrypting and decrypting side.

If you know the answer it would be great!

thanks,
John

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 2:15 pm
by jvierra
jsira2003@yahoo.com wrote:
Sat Jan 26, 2019 1:29 pm
I take it the erroractionpreference stop will stop function if an error is encounter after reporting message.
No it does not stop the function. It just causes and CmdLet to throw an exception that can be caught by a Try/Catch block. In this case the block causes the function to exit when there is an exception. The API calls will also cause an exception that is trapped by the "Catch" block.

See: help about_try_catch

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 2:17 pm
by jvierra
jsira2003@yahoo.com wrote:
Sat Jan 26, 2019 1:56 pm
I now have an error message. I am not sure why I have it but I think I'm going to learn more today. The message is: padding is invalid and cannot be removed

At this point I am not sure where to adjust it. From what I read the padding should be the same on both the encrypting and decrypting side.

If you know the answer it would be great!

thanks,
John
What code did you execute to get this message? If you inspect the compete error by reviewing the error stack it will tell you the issue.

Make this run correctly as a PS1 file and fix all errors before trying to package it.

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 2:28 pm
by jsira2003@yahoo.com
I executed my code with your error catching. I will see if I can catch error before packaging as you said in the ps studio. From what I read it seems as if the expected byte counts are off in the Encrypted string.

This is tricky stuff
John

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 2:30 pm
by jvierra
Here is a much better design for your code:

Code: Select all

Function DecryptUserKey{
    #requires -Version 3
    Param(
        [string]$File,
        [byte[]]$Key
    )
    
    $ErrorActionPreference = 'Stop'
    
    Try{
        $alllines = Get-Content $File
        
        foreach ($aline in $alllines) {
            $Secure2 = $aline | ConvertTo-SecureString -Key $Key
            ([System.Management.Automation.PSCredential]::New('N/A', $Secure2)).GetNetworkCredential().Password
        }
        
    }
    Catch{
        [System.Windows.Forms.MessageBox]::Show($_)
    }
    
}
The key not be saved in the code. You should save it in the registry and retrieve it when needed. This code also makes changing the key easier.

Note that there are no external dependencies in the function. It is called like this:

$userKey = DecryptUserKey -file <yourfile> -Key <your byte array>

Re: GetNetworkCredential difficulties

Posted: Sat Jan 26, 2019 2:35 pm
by jvierra
Here it is tested with my file and a blank key. I recommend starting with the default system key and once that works try adding a key. The function will tell you what is wrong with the key.
sapien3.png
sapien3.png (49.06 KiB) Viewed 1105 times