-1

I need to convert string to Base64 to use with an API call with AutoIt from PowerShell code. I tried below AutoIt functions with no luck, I also tried this answer.

$useragent="Power_7"
$result=[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($useragent));

With PowerShell I get cABvAHcAZQByAF8ANABfAFwAXABcAFwA. With below functions I get an empty string or a different result from PowerShell:

$input="Power_4")
$result=_Base64Encode($input)

Func _Base64Encode($input)
    $input = Binary($input)
    Local $struct = DllStructCreate("byte[" & BinaryLen($input) & "]")
    DllStructSetData($struct, 1, $input)
    Local $strc = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _
            "ptr", DllStructGetPtr($struct), _
            "int", DllStructGetSize($struct), _
            "int", 1, _
            "ptr", 0, _
            "ptr", DllStructGetPtr($strc))

    If @error Or Not $a_Call[0] Then
        Return SetError(1, 0, "") ; error calculating the length of the buffer needed
    EndIf

    Local $a = DllStructCreate("char[" & DllStructGetData($strc, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _
            "ptr", DllStructGetPtr($struct), _
            "int", DllStructGetSize($struct), _
            "int", 1, _
            "ptr", DllStructGetPtr($a), _
            "ptr", DllStructGetPtr($strc))

    If @error Or Not $a_Call[0] Then
        Return SetError(2, 0, ""); error encoding
    EndIf

    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Encode

Func _Base64Decode($input_string)
    Local $struct = DllStructCreate("int")
    Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", _
            "str", $input_string, _
            "int", 0, _
            "int", 1, _
            "ptr", 0, _
            "ptr", DllStructGetPtr($struct, 1), _
            "ptr", 0, _
            "ptr", 0)

    If @error Or Not $a_Call[0] Then
        Return SetError(1, 0, "") ; error calculating the length of the buffer needed
    EndIf

    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", _
            "str", $input_string, _
            "int", 0, _
            "int", 1, _
            "ptr", DllStructGetPtr($a), _
            "ptr", DllStructGetPtr($struct, 1), _
            "ptr", 0, _
            "ptr", 0)

    If @error Or Not $a_Call[0] Then
        Return SetError(2, 0, ""); error decoding
    EndIf

    Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

;---------------------------------------------------------------------------------
; Ascer
;==============================================================================================================================
; Function:         base64($vCode [, $bEncode = True [, $bUrl = False]])
;
; Description:      Decode or Encode $vData using Microsoft.XMLDOM to Base64Binary or Base64Url.
;                   IMPORTANT! Encoded base64url is without @LF after 72 lines. Some websites may require this.
;
; Parameter(s):     $vData      - string or integer | Data to encode or decode.
;                   $bEncode    - boolean           | True - encode, False - decode.
;                   $bUrl       - boolean           | True - output is will decoded or encoded using base64url shema.
;
; Return Value(s):  On Success - Returns output data
;                   On Failure - Returns 1 - Failed to create object.
;
; Author (s):       (Ghads on Wordpress.com), Ascer
;===============================================================================================================================
Func base64($vCode, $bEncode = True, $bUrl = False)
    Local $oDM = ObjCreate("Microsoft.XMLDOM")
    If Not IsObj($oDM) Then Return SetError(1, 0, 1)
    Local $oEL = $oDM.createElement("Tmp")
    $oEL.DataType = "bin.base64"

    If $bEncode then
        $oEL.NodeTypedValue = Binary($vCode)
        If Not $bUrl Then Return $oEL.Text
        Return StringReplace(StringReplace(StringReplace($oEL.Text, "+", "-"),"/", "_"), @LF, "")
    Else
        If $bUrl Then $vCode = StringReplace(StringReplace($vCode, "-", "+"), "_", "/")
        $oEL.Text = $vCode
        Return $oEL.NodeTypedValue
    EndIf

EndFunc ;==>base64
user4157124
  • 2,809
  • 13
  • 27
  • 42
  • Instead of using Unicode try UTF8 : $result=[System.Convert]::ToBase64String([System.Text.Encoding]::Utf8.GetBytes($useragent)); – jdweng Aug 04 '23 at 08:46
  • 1
    Is this for use for executing the base64 powershell, as if you run Powershell.exe /?, it gives you the instructions for doing that: `# To use the -EncodedCommand parameter: $command = 'dir "c:\program files" ' $bytes = [System.Text.Encoding]::Unicode.GetBytes($command) $encodedCommand = [Convert]::ToBase64String($bytes) powershell.exe -encodedCommand $encodedCommand` – KG-DROID Aug 04 '23 at 08:59
  • 2
    "*I tried below AutoIt functions with not luck* ..." AutoIt output is correct; of course it's different for different strings (`Power_7` and `Power_4`). Base64 `cABvAHcAZQByAF8ANABfAFwAXABcAFwA` is neither (it's "power_4_\\\\" UTF16 Little Endian). – user4157124 Aug 04 '23 at 15:48
  • Probably not related to your problem but I found that for the `CryptBinaryToString` call I had to add the `CRYPT_STRING_NOCRLF` flag to prevent linebreaks in output for large strings. So `"int", 1 + 0x40000000` instead of `"int", 1` – garbb Aug 04 '23 at 16:39

0 Answers0