“Openssl dgst -sha1” producendo un prefisso “(stdin) =” estraneo e trascinando la nuova riga


31

Se esegui questo comando sul tuo Unix

echo -n "foo" | openssl dgst -sha1

Otterrai questo risultato:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(seguito da una nuova riga).

Come posso forzare openssl a non mostrare il (stdin)=prefisso ed evitare la nuova riga finale?


@MarkDavidson Hmm, interessante. Sei sicuro che non aggiunga nemmeno una nuova riga?

Risposte:


22

Il formato binario non elaborato non aggiunge alcun output estraneo.
Output come binario quindi conversione in esadecimale:

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

Ti darò questo:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Questo metodo dovrebbe essere a prova di futuro nel caso in cui qualcuno decida di modificare nuovamente il formato di output testuale. Sono sicuro che correggeranno il prefisso come "SHA1 (stdin) =" per essere coerente con quello di un input di file.

Non posso credere che abbiano cambiato questo! Mi chiedo quanti script siano stati rotti.


4
Produrrà solo 20-30 ottetti per riga (o 40-60 caratteri). Per il checksum SHA-256, questo non è sufficiente a volte. Utilizzare l' -c 256opzione per estenderlo a 256 ottetti per riga.
Rockallite,

16

Osservo questo comportamento in OpenSSL 1.0.0e su Ubuntu 11.10, mentre OpenSSL 0.9.8k e 0.9.8t generano solo l'hash. La riga di comando di OpenSSL non è progettata per essere flessibile, è più un modo semplice per eseguire calcoli crittografici dalla riga di comando.

Se si desidera utilizzare OpenSSL, filtrare l'output:

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

Su Linux (con strumenti GNU o BusyBox), è possibile utilizzare sha1sum, che non richiede l'installazione di OpenSSL e ha un formato di output stabile. Stampa sempre un nome file, quindi rimuovilo.

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

Sui sistemi BSD incluso OSX, è possibile utilizzare sha1.

echo -n "foo" | sha1 -q

Tutti questi hanno generato il checksum in esadecimale seguito da una nuova riga. Il testo nei sistemi unix è sempre costituito da una sequenza di righe e ogni riga termina con un carattere di nuova riga. Se si memorizza l'output del comando in una variabile di shell, la nuova riga finale viene rimossa.

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

Se è necessario reindirizzare l'input in un programma che richiede un checksum senza newline finale (il che è davvero raro), rimuovere la newline.

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

questa è la situazione perfetta => copia e incolla la mappa della soluzione. Grazie!
oberstet

6

Ecco un'altra alternativa:

echo -n "foo" | openssl sha1 | awk '{print $2}'

1
So che la domanda si pone con questo formato specifico, tuttavia, se qualcuno cerca di estenderlo per includere i nomi dei file, potrebbe spezzarsi se il nome del file contiene spazi. Solo un avvertimento per le altre persone che atterrano qui.
Cameron Gagnon,

2

Ecco un modo per farlo usando built-in bash invece di pipe, awk, sed, tr, cut, ecc:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.