„Openssl dgst -sha1” produkujący zewnętrzny prefiks „(stdin) =” i końcowy znak nowej linii


31

Jeśli uruchomisz to polecenie na swoim Uniksie

echo -n "foo" | openssl dgst -sha1

Otrzymasz ten wynik:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(po którym następuje nowa linia).

Jak zmusić openssl, aby nie pokazywał (stdin)=prefiksu i unikał końcowego znaku nowej linii?


@MarkDavidson Hmm, ciekawe. Czy jesteś pewien, że nawet nie dodaje nowej linii?

Odpowiedzi:


22

Surowy format binarny nie dodaje żadnych dodatkowych danych wyjściowych.
Wyjście w postaci binarnej, a następnie konwersja na hex:

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

Dam ci to:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Ta metoda powinna być przyszłościowa na wypadek, gdyby ktoś postanowił ponownie zmienić tekstowy format wyjściowy. Jestem pewien, że poprawią prefiks na „SHA1 (stdin) =”, aby był zgodny z prefiksem pliku wejściowego.

Nie mogę uwierzyć, że to zmienili! Zastanawiam się, ile skryptów zostało złamanych.


4
Będzie wyprowadzał tylko 20-30 oktetów na wiersz (lub 40-60 znaków). W przypadku sumy kontrolnej SHA-256 czasami to nie wystarcza. Użyj -c 256opcji, aby rozszerzyć go do 256 oktetów na linię.
Rockallite,

16

Obserwuję to zachowanie w OpenSSL 1.0.0e na Ubuntu 11.10, podczas gdy OpenSSL 0.9.8k i 0.9.8t wyprowadza tylko skrót. Linia poleceń OpenSSL nie została zaprojektowana jako elastyczna, jest to raczej szybki i brudny sposób wykonywania obliczeń kryptograficznych z linii poleceń.

Jeśli chcesz użyć OpenSSL, odfiltruj dane wyjściowe:

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

W systemie Linux (z narzędziami GNU lub BusyBox) możesz używać sha1sum, który nie wymaga instalacji OpenSSL i ma stabilny format wyjściowy. Zawsze drukuje nazwę pliku, więc usuń ją.

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

W systemach BSD, w tym OSX, możesz używać sha1.

echo -n "foo" | sha1 -q

Wszystkie z nich generują sumę kontrolną w systemie szesnastkowym, po której następuje nowa linia. Tekst w systemach uniksowych zawsze składa się z sekwencji linii, a każda linia kończy się znakiem nowej linii. Jeśli przechowujesz dane wyjściowe polecenia w zmiennej powłoki, ostatnia nowa linia jest usuwana.

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

Jeśli potrzebujesz wprowadzić dane wejściowe do programu, który wymaga sumy kontrolnej bez końcowej nowej linii (co jest naprawdę rzadkie), usuń nową linię.

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

to idealna sytuacja => mapa rozwiązania kopiuj i wklej. dzięki!
oberstet

6

Oto kolejna alternatywa:

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

1
Wiem, że pytanie zadaje ten konkretny format, jednak jeśli ktoś spróbuje go rozszerzyć o nazwy plików, może się zepsuć, jeśli w nazwie pliku są spacje. Tylko heads up dla innych ludzi, którzy tu lądują.
Cameron Gagnon

2

Oto sposób na zrobienie tego za pomocą wbudowanych bashów zamiast rur, awk, sed, tr, cut itp.

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.