Using the Flow Designer PowerShell Step

lonesoac01
Giga Guru

Hello all,

 

     I have stumbled upon the PowerShell Step in Flow Designer. https://www.servicenow.com/docs/r/yokohama/build-workflows/workflow-studio/powershell-step-action-de... What I am really struggling with is the connection information.  I do not need to execute on a particular midserver as far as I know, I just need A server to run the below code.

 

The below is my powershell script.

 

param(
    [string]$ResponseBody,
    [string]$EncryptedSecret,
    [string]$ApiSecret = "",
    [switch]$SelfTest
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

function Get-OpenSslKeyIvFromPassphrase {
    param(
        [Parameter(Mandatory = $true)]
        [byte[]]$PassphraseBytes,

        [Parameter(Mandatory = $true)]
        [byte[]]$Salt,

        [int]$KeyLengthBytes = 32,
        [int]$IvLengthBytes = 16
    )

    $md5 = [System.Security.Cryptography.MD5]::Create()
    try {
        $derived = New-Object System.Collections.Generic.List[byte]
        $prev = [byte[]]@()

        while ($derived.Count -lt ($KeyLengthBytes + $IvLengthBytes)) {
            $input = New-Object byte[] ($prev.Length + $PassphraseBytes.Length + $Salt.Length)

            [Array]::Copy($prev, 0, $input, 0, $prev.Length)
            [Array]::Copy($PassphraseBytes, 0, $input, $prev.Length, $PassphraseBytes.Length)
            [Array]::Copy($Salt, 0, $input, $prev.Length + $PassphraseBytes.Length, $Salt.Length)

            $prev = $md5.ComputeHash($input)
            $derived.AddRange($prev)
        }

        $all = $derived.ToArray()

        $key = New-Object byte[] $KeyLengthBytes
        $iv = New-Object byte[] $IvLengthBytes

        [Array]::Copy($all, 0, $key, 0, $KeyLengthBytes)
        [Array]::Copy($all, $KeyLengthBytes, $iv, 0, $IvLengthBytes)

        return @{ Key = $key; IV = $iv }
    }
    finally {
        $md5.Dispose()
    }
}

function Decrypt-CryptoJsAesPassphrase {
    param(
        [Parameter(Mandatory = $true)]
        [string]$CipherTextBase64,

        [Parameter(Mandatory = $true)]
        [string]$Passphrase
    )

    $raw = [Convert]::FromBase64String($CipherTextBase64)
    if ($raw.Length -lt 16) {
        throw "Cipher text too short."
    }

    $header = [System.Text.Encoding]::ASCII.GetString($raw, 0, 8)
    if ($header -ne "Salted__") {
        throw "Unsupported format. Expected OpenSSL salted format that starts with Salted__."
    }

    $salt = New-Object byte[] 8
    [Array]::Copy($raw, 8, $salt, 0, 8)

    $cipherBytes = New-Object byte[] ($raw.Length - 16)
    [Array]::Copy($raw, 16, $cipherBytes, 0, $cipherBytes.Length)

    $passBytes = [System.Text.Encoding]::UTF8.GetBytes($Passphrase)
    $derived = Get-OpenSslKeyIvFromPassphrase -PassphraseBytes $passBytes -Salt $salt

    $aes = [System.Security.Cryptography.Aes]::Create()
    try {
        $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
        $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
        $aes.Key = $derived.Key
        $aes.IV = $derived.IV

        $decryptor = $aes.CreateDecryptor()
        try {
            $plainBytes = $decryptor.TransformFinalBlock($cipherBytes, 0, $cipherBytes.Length)
        }
        catch [System.Security.Cryptography.CryptographicException] {
            throw "Decrypt failed (invalid padding). This usually means the encrypted value and ApiSecret do not match, or the value was not encrypted with CryptoJS passphrase mode."
        }

        return [System.Text.Encoding]::UTF8.GetString($plainBytes)
    }
    finally {
        $aes.Dispose()
    }
}

function Encrypt-CryptoJsAesPassphrase {
    param(
        [Parameter(Mandatory = $true)]
        [string]$PlainText,

        [Parameter(Mandatory = $true)]
        [string]$Passphrase
    )

    $salt = New-Object byte[] 8
    [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($salt)

    $passBytes = [System.Text.Encoding]::UTF8.GetBytes($Passphrase)
    $derived = Get-OpenSslKeyIvFromPassphrase -PassphraseBytes $passBytes -Salt $salt

    $aes = [System.Security.Cryptography.Aes]::Create()
    try {
        $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
        $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
        $aes.Key = $derived.Key
        $aes.IV = $derived.IV

        $encryptor = $aes.CreateEncryptor()
        $plainBytes = [System.Text.Encoding]::UTF8.GetBytes($PlainText)
        $cipherBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length)

        $prefix = [System.Text.Encoding]::ASCII.GetBytes("Salted__")
        $combined = New-Object byte[] ($prefix.Length + $salt.Length + $cipherBytes.Length)

        [Array]::Copy($prefix, 0, $combined, 0, $prefix.Length)
        [Array]::Copy($salt, 0, $combined, $prefix.Length, $salt.Length)
        [Array]::Copy($cipherBytes, 0, $combined, $prefix.Length + $salt.Length, $cipherBytes.Length)

        return [Convert]::ToBase64String($combined)
    }
    finally {
        $aes.Dispose()
    }
}

if ($SelfTest) {
    $expected = "my-test-secret"
    $encrypted = Encrypt-CryptoJsAesPassphrase -PlainText $expected -Passphrase $ApiSecret
    $response = @{ encryptedSecret = $encrypted } | ConvertTo-Json -Compress

    $jsonData = $response | ConvertFrom-Json
    $newencryptedSecret = $jsonData.encryptedSecret
    $newSecret = Decrypt-CryptoJsAesPassphrase -CipherTextBase64 $newencryptedSecret -Passphrase $ApiSecret

    if ($newSecret -ne $expected) {
        throw "Self-test failed: decrypted value does not match expected."
    }

    $result = @{ decryptedSecret = $newSecret; message = "Self-test passed." } | ConvertTo-Json -Compress
    Write-Host $result
    return
}

if ([string]::IsNullOrWhiteSpace($EncryptedSecret)) {
    if ([string]::IsNullOrWhiteSpace($ResponseBody)) {
        throw "Provide -EncryptedSecret directly, -ResponseBody with JSON containing encryptedSecret, or run with -SelfTest."
    }

    $jsonData = $ResponseBody | ConvertFrom-Json
    $newencryptedSecret = $jsonData.encryptedSecret
}
else {
    $newencryptedSecret = $EncryptedSecret
}

$newSecret = Decrypt-CryptoJsAesPassphrase -CipherTextBase64 $newencryptedSecret -Passphrase $ApiSecret

$result = @{ decryptedSecret = $newSecret } | ConvertTo-Json -Compress
Write-Host $result

 

 

0 REPLIES 0