Posted On July 28, 2020

PowerShell: Coverting Hex or Bytes Array to ASCII

kimconnect 0 comments
blog.KimConnect.com >> Windows >> PowerShell: Coverting Hex or Bytes Array to ASCII

The following is an illustration of a practical usage of decrypting an ASCII encoded value from a CRM database. This is also a solution for the issue of “Recovering ‘lost’ CRM encryption key.” May the power of Google helps someone who is facing such problems.

# getCrmEncryptionPassword.ps1

$orgName='TESTORG'
$sqlServer='SQLSERVER'
$saUsername='sa'
$saPassword='password'
$saCredential=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $saUsername,$(ConvertTo-securestring $saPassword -AsPlainText -Force)

function getSymmetricKey($orgName){
    $moduleName='sqlps'    
    if(!(Get-Module -ListAvailable -Name $moduleName -ea SilentlyContinue)){
        if(!('NuGet' -in (get-packageprovider).Name)){    
            try{
                Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction SilentlyContinue;
                }
            catch{
                #Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
                #Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
                Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction SilentlyContinue;
                }            
            }
        Install-Module -Name $moduleName -Force -Confirm:$false
        }
    import-module $moduleName  
    $querySymmetricKey=@"
        USE MSCRM_CONFIG
        SELECT VarBinaryColumn FROM OrganizationProperties
        WHERE (ColumnName = 'SymmetricKeySource')
        AND Id IN (SELECT Id FROM Organization WHERE UniqueName = '$orgName')
"@
    $symmetricKey=invoke-sqlcmd $querySymmetricKey
    return $symmetricKey.VarBinaryColumn
}

$encodedBytes=Invoke-Command -ComputerName $sqlServer -Credential $saCredential -ScriptBlock{
                param($getSymmetricKey,$orgName)
                write-host "Executing function on $env:computername"
                Write-Host "$getSymmetricKey"
                pause
                [ScriptBlock]::Create($getSymmetricKey).invoke($orgName)
                } -Args ${function:getSymmetricKey},$orgName

function convertEncodedBytesToString($bytesArray,$encoding='default'){
    # Convert encoded bytes => decimal string => decimal bytes array => string
    #source: https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter.tochar?view=netcore-3.1
    $ErrorActionPreference='stop'
    try{
        $decimalString=[System.Text.Encoding]::default.GetChars($bytesArray) -join ''
        $decimalBytes=$decimalString.Split(':')
        $result=$(for ($i=0;$i -lt $decimalBytes.count;$i+=2){[System.BitConverter]::ToChar($decimalBytes,$i)}) -join ''
        return $result
    }catch{
        Write-Error $_
        return $false
        }
}

convertEncodedBytesToString $encodedBytes
# Other Miscellaneous conversions

function convertHexToAscii($hexValue){
    try{
        $initChars=$hexValue.ToString().Substring(0,2)
        $startIndex=if($initChars -eq '0x'){2}else{0}
        $keys=$hexValue -split '-'
        $decimalBytes = $(for($i=$startIndex; $i -lt $keys.length; $i+=2){[char][int]::Parse($keys.substring($i,2),'HexNumber')}) -join ''
        $decimalArray=$decimalBytes.Split(':')
        $ascii=$(for ($i=0;$i -lt $decimalArray.count;$i+=2){[CHAR][BYTE]$decimalArray[$i]}) -join ''
        return $ascii
    }catch{
        Write-Warning "Please validate the input by checking this error:`r`n$($Error[0].Exception.Message)"
        }
}

function convertBytesArrayToAscii($bytesArray){
    function convertDecimalBytesToAscii($decimalBytes){    
        $decimalArray=$decimalBytes.Split(':')
        $ascii=$(for ($i=0;$i -lt $decimalArray.count;$i+=2){[CHAR][BYTE]$decimalArray[$i]}) -join ''
        return $ascii
        }

    function convertBytesArrayToDecimalBytes($bytesArray){
        return [System.Text.Encoding]::ASCII.GetString($bytesArray)
        }
    try{
        $decimalBytes=convertBytesArrayToDecimalBytes $bytesArray
        $ascii=convertDecimalBytesToAscii $decimalBytes
        return $ascii
        }
    catch{
        write-warning $error[0].Exception.Message
        }
}

# How to convert Bytes Array => Hex
$hexValue=[System.BitConverter]::ToString($bytesArray)

# How to convert decimalBytes => ASCII
$decimalBytes=($hexValue.split('-') | % {[char][byte]"0x$_"}) -join ''

# How to convert bytes => binary
[system.Text.Encoding]::Default.GetBytes($bytesArray) | %{[System.Convert]::ToString($_,2).PadLeft(8,'0') }

# Enable UTF8 encoding in PShell session
$OutputEncoding=[console]::InputEncoding=[console]::OutputEncoding=New-Object System.Text.UTF8Encoding

# Convert text => bytes
$text='hello world!'
$bytes = [System.Text.Encoding]::UTF8.GetBytes($text)

# How to convert bytes => text
[System.Text.Encoding]::UTF8.GetChars($bytes) -join ''

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post

Transfer DHCP Scopes Between Windows Servers

When a new DHCP server is introduced into the system, it's often necessary to configure…

Enabling Unix Newline ‘LF’ Support for Windows 10 Version 1706 or Higher

Please note that the following PoSH commands won't work on earlier versions of Windows (e.g.…

Implement Docker & Portainer

Prerequisites:OS: base image Centos 7 Create network bridge from command line: # Network: x.x.x.128/26 Range:…