How-to manually HMAC data with transit key


I would like to realize the same HMAC as transit does but manually.


Based on this subject, I wanted to try to realize the same HMAC as Vault do it in a transparent way with the transit module.

Key creation

curl --header "X-Vault-Token: <my-token>" --request POST --data '{"exportable":true}'

HMAC Input

curl --header "X-Vault-Token: <my-token>" --request POST --data '{"input":"Benjamin"}'

I got as HMAC output : "hmac":"vault:v1: gydrd9I34QfKaVWkcQpe9XkQMKcfcSPJX3wdm4MyMyI=

Key Export

curl --header "X-Vault-Token: <my-token>"
Key output is : "1":"BCUP9OOhYJJLkdJOpQBWCjtCMPaj4hSEg8aAqfF0T5c="

Until here everything worked perfectly as described into the documentation.

The goal is now to try to do the HMAC by myself, outside of the vault. So I made a Go script to try to make it works, but it didn’t work as planned…

Go Script

import (

func main() {
    rawInput := base64.StdEncoding.EncodeToString([]byte("Benjamin"))
    input,_ := base64.StdEncoding.DecodeString(rawInput)
    key_raw, _ := base64.StdEncoding.DecodeString("BCUP9OOhYJJLkdJOpQBWCjtCMPaj4hSEg8aAqfF0T5c=")
    hf := hmac.New(sha256.New, key_raw)
    retBytes := hf.Sum(nil)
    retStr := base64.StdEncoding.EncodeToString(retBytes)

And the returned HMAC is : qxflJNRlCV5ubTr8S+In7F4DUfoC4z6IoE0q2duRbSs=

Unfortunately it isn’t the same as the expected (gydrd9I34QfKaVWkcQpe9XkQMKcfcSPJX3wdm4MyMyI=) :sweat_smile:

Suggested issue

I guess that what I am doing wrong is the formating of the key and/or the input.

But after 5 hours spent on this issue, I haven’t any idea left…
Would anyone has some insight on it ?
Thanks !

Ok I am dumb af…


By default the input should be base64 encoded… So the vault hmac request should be curl --header "X-Vault-Token: <my-token>" --request POST --data '{"input":"QmVuamFtaW4="}'

Bug report

But the Vault UI HMAC feature in ui/vault/secrets/transit/actions/<key>?action=hmac is bugged and consider the input as “not base64 encoded”. Even if the base 64 checkbox is ticked !