2

I'd like to compute a HMAC-SHA512 digest in my bash script. So far I've found only this repeated many times over many different sites.

echo -n message | openssl dgst -sha256 -hmac secret -binary >message.mac

Apparently no one posting this realizes this is not the proper way to pass a secret string to a program as the secret will be visible in the process list for every other process running on the system. Is there any other way (perhaps with other tool) to easily make an HMAC in the shell with better interface for passing secrets?

UPDATE

I use the following tool (~/bin/hmac) now. It takes the key from the MACKEY environment variable.

#!/usr/bin/env python3
import hmac, sys, os

key    = os.environ['MACKEY'].encode('utf-8')
algo   = os.getenv('MACALGO', 'sha512')
digest = hmac.new(key, digestmod = algo)

while True:
    buf = sys.stdin.buffer.read(512)
    if not buf:
        break
    digest.update(buf)

print(digest.hexdigest())

Usage:

echo -n message | MACKEY=foobar hmac
  • Where is the secret now? (Just before the openssl call) – Jeff Schaller Jan 26 '18 at 12:50
  • -passin would support envvars or files, but I can't see anything like that for a MAC key... And no, -passin itself doesn't work. – ilkkachu Jan 26 '18 at 13:02
  • if you want to just hide the process from other users on the machine, you can remount /proc with hidepid=2: mount -o remount,rw,hidepid=2 /proc - don't forget to update fstab if you want /proc persistently mounted like that: proc /proc proc defaults,hidepid=2 0 0. NB: this will obviously not be useful in your situation if you're trying to hide the secret entirely from ps/top outputs for all users. – RobotJohnny Jan 26 '18 at 13:15
  • @JeffSchaller In an environment variable where it got from file via cat keys | { read api_key; read api_secret }. – Mark Howard Jan 26 '18 at 13:35
  • Check out Hide arguments to program.... – meuh Jan 26 '18 at 16:12
2

Re-directions are not part of the argument list.

This are considered safe from ps snooping:

cmd </file/key
cmd <<<"key"

Un-named pipes are also possible inside an script

echo "secret" | cmd

Example of secure password passing

So, this script is regarded as secure:

#!/bin/bash

read secretkey </dev/stdin

var="<?= hash_hmac(\"sha512\", \"$1\", \"$secretkey\"); ?>"

php7.1 <<<"$var"

The </dev/stdin could be replaced with a </dir/keyfile if the key could be stored in a file.

For the stdin version, use it as this:

./script "Message" <<<"secretkey"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.