I came across the following command for unix on binance which I was trying to unpack. See here: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md

(Section: SIGNED Endpoint Examples for POST /api/v1/order)

openssl dgst -sha256 -hmac

What I understand is it is a call to the openssl command to produce a digest, the digest will be of the sha256 variety as agreed on by standard specs. What I don't understand is the -hmac flag. What is it and what does it do down to a mathematical level?

My Attempt at Solving the Problem:

I did a google search with openssl -hmac and openssl dgst -hmac but the top 10 results were of not avail to me. So I imagine more experienced users would be better to ask.


The flag isnt mentioned in these docs: https://www.mkssoftware.com/docs/man1/openssl_dgst.1.asp and so I'm starting to believe it may have no cryptographic purpose. Although i'm right now not sure.

I found what looks similar to the flag mentioned in This Question: https://stackoverflow.com/questions/7285059/hmac-sha1-in-bash


2 Answers 2


HMAC is also called a keyed hash. So you can only generate the same hash during verification if you have the same key used during signature generation. The result of the MAC is called an authentication tag.

HMAC is a special construct that uses two calls to the hash - in your case SHA-256 - that is used internally, and it doesn't use any other cryptographic primitives. It could therefore be seen as a specific mode of the hash itself. Hence the inclusion in dgst.

Missing from your code is the key data, which is of course required to create a keyed hash. This should be presented after -hmac. Unfortunately openssl requires a binary format of the key. For more info see this old conversation on the OpenSSL mailing list.

EDIT #1: Digging a bit deeper, if you want to specify the key as hexadecimals you could use a line like this:

echo -n "Hello world!" | openssl dgst -sha256 -mac hmac -macopt hexkey:01020304

The output of the function is the output of the second run of the hash, so it is indistinguishable from just SHA-256 if you just look at the size of the hash / HMAC result. Of course the contents will be completely different from just hashing the data (or key and data concatenated).

EDIT #2: However, you haven't specified a key, so actually HMAC is skipped and SHA-256 is used. This has been flagged as a bug, see here

  • 1
    In this API (following the link) they use an ASCII form key, ( a long base64 string) which is then used as an argument after -hmac. If you wanted to use binary keys, you'd have to convert them to hex-strings (as in the enc -K option) and use an alternative form of the command openssl dgst -sha256 -mac HMAC -macopt hexkey:ABCDEF0102 e.g.
    – Henno
    Apr 7, 2018 at 7:29
  • Of course, entropy-wise it doesn't matter if we use an ASCII-fied key NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j or the equivalent 48 raw bytes. It's common practice in such API-calls to base64 everything so that string methods (or arguments) just work. HTTP prefers ASCII too (for the API keys in headers, etc.)
    – Henno
    Apr 7, 2018 at 7:37
  • 1
    If someone is using this command to validate libcrypto code, don't forget that if you have const unsigned char data[] = "Hello world!" then the command should have echo -ne "Hello world!\0" with the explicit null terminator.
    – Daniel
    Oct 11, 2019 at 16:57

my 2 cents if You are on iOS (or Mac OS...) tired of messing around I wrote it..


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .