"Openssl dgst -sha1" que produce un prefijo "(stdin) =" extraño y una nueva línea final

31

Si ejecuta este comando en su Unix

echo -n "foo" | openssl dgst -sha1

Obtendrá esta salida:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(seguido de una nueva línea).

¿Cómo puedo forzar openssl para que no muestre el (stdin)=prefijo y evitar la nueva línea final?

Kevdog777
fuente
@ MarkDavidson Hmm, interesante. ¿Estás seguro de que ni siquiera agrega una nueva línea?

Respuestas:

22

El formato binario sin formato no agrega ninguna salida extraña.
Salida como binario y luego convertir a hexadecimal:

echo -n "foo" | openssl dgst -sha1 -binary | xxd -p

Te daré esto:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Este método debe estar preparado para el futuro en caso de que alguien decida cambiar nuevamente el formato de salida de texto. Estoy seguro de que corregirán el prefijo "SHA1 (stdin) =" para que sea coherente con el de una entrada de archivo.

¡No puedo creer que hayan cambiado esto! Me pregunto cuántos scripts se rompieron.

Hacker malvado
fuente
44
Solo generará entre 20 y 30 octetos por línea (o entre 40 y 60 caracteres). Para la suma de comprobación SHA-256, esto no es suficiente a veces. Use la -c 256opción para extenderlo a 256 octetos por línea.
Rockallite
16

Observo este comportamiento en OpenSSL 1.0.0e en Ubuntu 11.10, mientras que OpenSSL 0.9.8k y 0.9.8t generan solo el hash. La línea de comandos de OpenSSL no está diseñada para ser flexible, es más una forma rápida y sucia de realizar cálculos criptográficos desde la línea de comandos.

Si desea utilizar OpenSSL, filtre la salida:

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //'

En Linux (con herramientas GNU o BusyBox), puede usar sha1sum, que no requiere la instalación de OpenSSL y tiene un formato de salida estable. Siempre imprime un nombre de archivo, así que quítelo.

echo -n "foo" | sha1sum | sed 's/ .*//'

En los sistemas BSD, incluido OSX, puede usar sha1.

echo -n "foo" | sha1 -q

Todos estos generan la suma de comprobación en hexadecimal seguido de una nueva línea. El texto en sistemas unix siempre consta de una secuencia de líneas, y cada línea termina con un carácter de nueva línea. Si almacena la salida del comando en una variable de shell, la nueva línea final se elimina.

digest=$(echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //')

Si necesita canalizar la entrada en un programa que requiere una suma de comprobación sin una nueva línea final (lo cual es realmente raro), elimine la nueva línea.

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //' | tr -d '\n' | unusual_program
Gilles 'SO- deja de ser malvado'
fuente
esta es la situación perfecta => copiar y pegar mapa de soluciones. ¡Gracias!
oberstet
6

Aquí hay otra alternativa:

echo -n "foo" | openssl sha1 | awk '{print $2}'
Vishnu Kumar
fuente
1
Sé que la pregunta se hace con este formato específico, sin embargo, si alguien intenta extender esto para incluir nombres de archivo, podría romperse si el nombre de archivo tiene espacios. Solo un aviso para otras personas que aterrizan aquí.
Cameron Gagnon
2

Aquí hay una manera de hacerlo usando bash incorporado en lugar de tuberías, awk, sed, tr, cut, etc.

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
al-x
fuente