4

I'm trying to use OpenSSL to generate a checksum in CMD, as per the top answer here.

However, using the provided example I get an unexpected result:

C:\>echo -n "value" | openssl dgst -sha1 -hmac "key"
(stdin)= 8c5b4c3a9cee7bc9020a43f1c396f9e13c2bae4a

The expected result as shown in the original question, which I also get with other HMAC SHA1 generators is:

57443a4c052350a44638835d64fd66822f813319

Curiously, I get a third result in PowerShell:

PS C:\> echo -n "value" | openssl sha1 -hmac "key"
(stdin)= 56d96e5393d98eb5e189ab189e02b1832af727b5

As might be self evident, I'm a bit out of my comfort zone here, so forgive me for any obvious mistakes or shortcomings in my explanation.

Alex
  • 55
  • 3
  • Not sure what the dos prompt outputs for echo -n, but powershell does not have that option for suppressing line feed (ie it still outputs an extra line feed at the end and calculates the sum including that character) – Joachim Isaksson Jan 05 '21 at 09:09
  • `echo -n "value" | openssl dgst -sha1 -hmac "key"` results in passing to `openssl` a byte stream with following hexadecimal values: `2D 6E 20 22 76 61 6C 75 65 22 20 0D 0A`. I doubt that you really want to get the hash value of `-n "value" CRLF` (CRLF = carriage return + line-feed). PowerShell is a different script interpreter than Windows command processor. Its syntax is completely different. For that reason `echo` is interpreted different by `powershell.exe` in comparison to `echo` interpreted by `cmd.exe`. So for which string (byte stream) do you really want the hash value? – Mofi Jan 05 '21 at 10:13
  • BTW: The referenced question is for `bash` – a Unix/Linux shell interpreter which interprets its internal command `echo` different to `cmd.exe` and `powershell.exe` of Windows. You cannot compare the results of three different interpreters each interpreting `echo` different on using a `bash` command line. – Mofi Jan 05 '21 at 10:19
  • PS: `echo -n "value" >OutputCMD.txt` writes the byte stream `2D 6E 20 22 76 61 6C 75 65 22 20 0D 0A` into the text file `OutputCMD.txt` (ASCII character stream). A space left to a redirection operator like `|` or `>` is also output by `echo` of `cmd.exe`. `echo -n "value" >OutputPS.txt` executed in a PowerShell prompt window writes the byte stream `FF FE 2D 00 6E 00 0D 00 0A 00 76 00 61 00 6C 00 75 00 65 00 0D 00 0A 00` into the file `OutputPS.txt` (UTF-16 Little Endian encoded Unicode character stream with byte order mark). `bash` outputs with the used `bash` options just `76 61 6C 75 65`. – Mofi Jan 05 '21 at 10:36
  • Thanks so much for your comments. It's clear I'm messing with something a little out of my league here. :) What I'm trying to achieve is create a batch script to HMAC a string using a key. Finding the linked question, I believed to be on the correct path. It appears I'd need to rephrase my question. :) – Alex Jan 05 '21 at 11:05

1 Answers1

3

Scraping together answers to several questions on SO teaches some tricks to get the same result for all three cases:

In *nix-like environments (including macOS), printf is a more portable way to print without a newline:

$ printf value | openssl dgst -sha1 -hmac key
57443a4c052350a44638835d64fd66822f813319

A trick to avoid the newline in CMD (note that there is no space before the second |, this is essential):

>echo | set /p=value| openssl dgst -sha1 -hmac key
(stdin)= 57443a4c052350a44638835d64fd66822f813319

With PowerShell this does not seem possible "natively" at the moment, according to this issue in the PowerShell GitHub project: Piping Text To An External Program Appends A Trailing Newline. If you really have to do it from a PowerShell prompt, a hack could be to invoke CMD, like this:

> cmd /c "echo | set /p=value| openssl dgst -sha1 -hmac key"
(stdin)= 57443a4c052350a44638835d64fd66822f813319
Reinier Torenbeek
  • 16,669
  • 7
  • 46
  • 69