18

I have the following byte array that I would like to obtain hex format in order to decrypt an encrypted string using aes-256-ecb. (PowerShell uses AES encryption if you specify key argument in ConvertFrom-SecureString function)

0 54 0 48 0 49 0 99 0 48 0 98 0 97 0 45 0 50 0 50 0 97 0 57 0 45 0 49 0 49 0 101

In order to check this I verify by using openssl:

echo 'mysecretdata' | openssl enc -d -aes-256-ecb -K 303534303438303439303939303438303938303937303435303530303530303937303537303435303439303439303130310a

hex string is too long invalid hex key value

What am I missing?

5 Answers 5

30

You can use the X2 format string on each individual byte to get it's hex representation, then use the -join operator to concatenate the strings:

$bytes = 0,54,0,48,0,49,0,99,0,48,0,98,0,97,0,45,0,50,0,50,0,97,0,57,0,45,0,49,0,49,0,101
$hexString = ($bytes|ForEach-Object ToString X2) -join ''

(If that's your actual key, you might want to refrain from ever using it again, now that it's public knowledge ;-) )

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Mathias! now the hex key value seems correct but now I see a decryption error. bad decrypt 140097927906968:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:evp_enc.c:518: ծGPQ3¬S/2d)k~Jjz+-
From your example it looks like you're trying to decrypt the plaintext (which doesn't make sense) and supplying the ciphertext as the key
Actually I am trying to use this string (previous one was just an example): $echo 76492d1116743f0423413b16050a5345MgB8AHoATQBZAEMAVgAyAG4ATQBOAGIAZABRAHIAMAA0AEUANgBKAFUAUABXAHcAPQA9AHwAYQAzADkANAAwADMAMQAzAGMAMgA1AGUAZAAxAGQAZQA1ADUAZgA2AGEAMgA2ADQAYQA2ADAAZQA5AGYANQBjAGEANgBkAGYAZQA1ADkAYQA5AGIANgBmAGYAYgBjADQAZgBiADcAMABiADAAYgBhADQAMABkADIAMAA3AGEAZgA= | openssl enc -d -aes-256-ecb -K 0036003000310063003000620061002D0032003200610039002D003100310065 )2Ap@$ bad decrypt 140645963531928:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:evp_enc.c:518:
18

You can use the string System.BitConverter::ToString(byte[] value) static method if you're fine with hyphenation:

PS> $bytes = 0,7,14,21,28,35,42
PS> [System.BitConverter]::ToString($bytes)
00-07-0E-15-1C-23-2A
PS>
PS> # If you'd like to use this in a pipeline:
PS> ,$bytes | % { [System.BitConverter]::ToString($_) }
00-07-0E-15-1C-23-2A
PS>
PS> # If you can't obtain a byte[]-compatible input:
PS> $bytes | . { [System.BitConverter]::ToString(@($input)) }
00-07-0E-15-1C-23-2A

The comma operator (,) makes sure that your byte array (or object castable to such) is passed in (via ForEach-Object (%) running the script block over a 1-element array) as it is, and not iterated over.

If that's unavoidable, then the latter example uses the dot sourcing operator (.), a script block, and the array subexpression operator (@( )) to collect the items from the $input automatic function variable (an IEnumerator, not IEnumerable) and produce an array ToString's happy with.

Comments

6

It sounds like you're looking for a "hex byte string" representation of a byte array, specifically a separator-less concatenation of 2-hex-digits-per-byte string representations, such as '090AFF' for a byte array with (decimal) values 9, 10, and 255

To offer .NET API-based solutions - as an alternative to the PowerShell-native solutions offered - which are both more convenient and perform better:

  • In PowerShell (Core) 7+ / .NET 5+: Use [Convert]::ToHexString() (and [Convert]::FromHexString()), which directly support converting to (and from) the desired "hex byte string" format, i.e. a separator-less string of 2-hex-digits-per-byte representations.

      # PowerShell 7+ only.
    
      [byte[]] $bytes = 9, 10, 255
    
      # -> '090AFF'
      [Convert]::ToHexString($bytes)
    
  • In Windows PowerShell: Use [BitConverter]::ToString(), but invariably uses - separation; however, you can easily strip these separators by appending -replace '-'

      # Windows PowerShell (too).
    
      [byte[]] $bytes = 9, 10, 255
    
      # -> '090AFF'
      [BitConverter]::ToString($bytes) -replace '-'
    

Comments

2

While the currently most upvoted answer here suggests using the pipeline, I suggest using the ForEach method like so:

$bytes = -split '0 54 0 48 0 49 0 99 0 48 0 98 0 97 0 45 0 50 0 50 0 97 0 57 0 45 0 49 0 49 0 101' -as 'byte[]'
$hexString = -join $bytes.ForEach('ToString','X2')  # for a lowercase string, use 'x2' instead of 'X2'

You can read more about how I use ForEach here from this detailed breakdown of the ForEach & Where methods provided by this powershellmagazine.com article (archive.org) (archive.today). Alternatively, here's a trimmed down version of the relevant section that I came up with:

ForEach(string methodName) / ForEach(string methodName, object[] arguments)

Provide the method name as the first argument; any proceeding arguments provided will be passed to that method.

$str = 'Foo', 'BAR', 'loRem', 'ipsum'

# Output each string as lowercase
$str.ForEach('ToLower')
$dt = [datetime]'2023-01-04', [datetime]'2022-04-12', [datetime]'2021-10-30'

# Output with a year deducted from each date
$dt.ForEach('AddYears',-1)

Comments

1

This is a generic way to convert a byte-array into a HexString via .NET framework:

$array  = [byte[]](1..15)
$hexbin = [System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary]::new()
$hexbin.Value = $array
$hexString = $hexbin.ToString()

gives this result: 0102030405060708090A0B0C0D0E0F

and into the other direction it goes like this:

$bytes = [System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary]::Parse($hexString).Value

In your original question I dont see an array at all, but an AES256 key must be exact 32 bytes long (represented by a 64-characters hexstring). Your hexsting has a length of 100 characters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.