"Openssl dgst -sha1" створює сторонній префікс "(stdin) =" і виводить новий рядок


31

Якщо ви запускаєте цю команду у своєму Unix

echo -n "foo" | openssl dgst -sha1

Ви отримаєте цей вихід:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(далі новий рядок).

Як я можу змусити openssl не показувати (stdin)=префікс та уникнути останнього нового рядка?


@MarkDavidson Хм, цікаво. Ви впевнені, що він навіть не додає новий рядок?

Відповіді:


22

Сирий бінарний формат не додає сторонніх результатів.
Виведіть як двійковий, а потім перетворіть у шістнадцятковий:

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

Дамо вам це:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Цей метод повинен бути надійним у випадку, якщо хтось вирішить знову змінити формат тексту тексту. Я впевнений, що вони виправлять префікс "SHA1 (stdin) =", щоб він відповідав введенню файлу.

Я не можу повірити, що вони змінили це! Цікаво, скільки скриптів було порушено.


4
Він виведе лише 20-30 октетів на рядок (або 40-60 символів). Для контрольної суми SHA-256 іноді цього недостатньо. Скористайтеся -c 256опцією, щоб розширити її до 256 октетів на рядок.
Rockallite

16

Я спостерігаю таку поведінку під OpenSSL 1.0.0e на Ubuntu 11.10, тоді як OpenSSL 0.9.8k та 0.9.8t виводить лише хеш. Командний рядок OpenSSL не розроблений так, щоб бути гнучким, це скоріше швидкий і брудний спосіб виконання криптографічних обчислень з командного рядка.

Якщо ви хочете використовувати OpenSSL, відфільтруйте вихід:

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

У Linux (з інструментами GNU або BusyBox) ви можете використовувати sha1sum, що не вимагає встановлення OpenSSL і має стабільний вихідний формат. Він завжди друкує ім'я файлу, тому зніміть його.

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

У системах BSD, включаючи OSX, ви можете використовувати sha1.

echo -n "foo" | sha1 -q

Усі ці дані виводять контрольну суму в шістнадцятковому знаку з наступним рядком. Текст у системах unix завжди складається з послідовності рядків, і кожен рядок закінчується символом нового рядка. Якщо ви зберігаєте вихід команди в змінній оболонки, остаточний новий рядок знімається.

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

Якщо вам потрібно передати вхід в програму, яка вимагає контрольної суми без остаточного нового рядка (що дійсно рідко), зніміть новий рядок.

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

це ідеальна ситуація => скопіювати та вставити карту рішення. Спасибі!
оберстет

6

Ось ще одна альтернатива:

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

1
Я знаю, що запитання задається у цьому конкретному форматі, однак, якщо хтось спробує розширити це, щоб включити імена файлів, він може зламатися, якщо в назви файлу є пробіли. Просто голова вгору для інших людей, які тут приземляються.
Камерон Ганьон

2

Ось спосіб це зробити за допомогою вбудованих bash замість труб, awk, sed, tr, cut тощо:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.