2011-09-02 20 views
67

¿Hay un script bash para generar un hash HMAC-SHA1?HMAC-SHA1 en bash

Busco algo equivalente al siguiente código PHP:

hash_hmac("sha1", "value", "key"); 

Respuesta

135

Comprendo que esto no es exactamente lo que estás pidiendo, pero no hay ningún punto en reinventar la rueda y escribir una fiesta versión.

Puede simplemente usar el comando openssl para generar el hash dentro de su secuencia de comandos.

[[email protected]] echo -n "value" | openssl dgst -sha1 -hmac "key" 
57443a4c052350a44638835d64fd66822f813319 

O simplemente:

[[email protected]] echo -n "value" | openssl sha1 -hmac "key" 
57443a4c052350a44638835d64fd66822f813319 

recuerde utilizar -n con echo o bien un carácter de salto de línea se anexa a la cadena y que cambia sus datos y el hash.

Ese comando proviene del paquete OpenSSL que ya debería estar instalado (o instalarse fácilmente) en su elección de Linux/Unix, Cygwin y similares.

Tenga en cuenta que las versiones anteriores de openssl (como las enviadas con RHEL4) pueden no proporcionar la opción -hmac.


Como solución alternativa, pero sobre todo para demostrar que los resultados son los mismos, también podemos llamar a PHP de hmac_sha1() desde la línea de comandos:

[[email protected]]$ echo '<?= hash_hmac("sha1", "value", "key") ?>' | php 
57443a4c052350a44638835d64fd66822f813319 
+0

Las implementaciones de OpenSSL son muy lentas.Si tiene que hacerlo de vez en cuando, está bien, pero si está tratando de calcular cantidades masivas de hash, quiere investigar diferentes avenidas. – Marcin

+1

@Marcin: ¿puedes citar una fuente con eso? – sehe

+0

[John The Ripper] (http://www.openwall.com/john/) es muy rápido para las implementaciones de CPU y es de código abierto. – Marcin

30

Aquí es una función bash que funciona como hash_hmac de PHP:

#!/bin/bash 

function hash_hmac { 
    digest="$1" 
    data="$2" 
    key="$3" 
    shift 3 
    echo -n "$data" | openssl dgst "-$digest" -hmac "$key" "[email protected]" 
} 

# hex output by default 
hash_hmac "sha1" "value" "key" 

# raw output by adding the "-binary" flag 
hash_hmac "sha1" "value" "key" -binary | base64 

# other algos also work 
hash_hmac "md5" "value" "key" 
+0

Esa es una buena manera de concluirlo. +1 –

+2

gracias por -binary :) – Manav

+0

+1 porque a diferencia de la respuesta seleccionada, esta responde la pregunta. (Aunque ambos son útiles) –

2

Gracias por la función hash_hmac! Pero no fue suficiente para mi aplicación. En caso de que alguien se preguntara, tuve que volver a manipular cosas varias veces utilizando una clave que fue el resultado del hashing anterior, y por lo tanto es una entrada binaria. (La firma de autenticación de Amazon AWS se crea así.)

Entonces, lo que necesitaba era una forma de suministrar la clave binaria de una manera que no rompa el algoritmo. Luego encontré esto: http://openssl.6102.n7.nabble.com/command-line-hmac-with-key-in-hex-td6754.html

La respuesta de Stephen Henson requiere que la función hash_hmac devuelva el valor en formato hexadecimal. Por lo que debe hacerse eco de lo siguiente:

$ echo -n "$data" | openssl dgst "-$digest" -hmac "$key" | sed -e 's/^.* //' 

A continuación, la siguiente llamada tendría que proporcionar la clave como Hexit:

$ echo -n "$data" | openssl dgst "-$digest" -mac HMAC -macopt "hexkey:$key" | sed -e 's/^.* //' 

Esperemos que esto ayuda a nadie, probablemente alguien que está tratando de crear scripts bash para invalidar las entradas de CloudFront en AWS (como yo!) (No lo he probado todavía, pero creo que esta es la causa de por qué mi script bash no funciona, y mi PHP lo hace ...)