“Openssl dgst -sha1” menghasilkan awalan “(stdin) =” yang tidak dikenal dan mengikuti baris baru

31

Jika Anda menjalankan perintah ini di Unix Anda

echo -n "foo" | openssl dgst -sha1

Anda akan mendapatkan hasil ini:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(diikuti oleh baris baru).

Bagaimana saya bisa memaksa openssl untuk tidak menunjukkan (stdin)=awalan, dan menghindari baris baru yang tertinggal?

Kevdog777
sumber
@MarkDavidson Hmm, menarik. Apakah Anda yakin itu bahkan tidak menambahkan baris baru?

Jawaban:

22

Format biner mentah tidak menambahkan output asing.
Output sebagai biner kemudian dikonversi ke hex:

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

Akan memberi Anda ini:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Metode ini harus menjadi bukti di masa depan jika seseorang memutuskan untuk mengubah format output tekstual lagi. Saya yakin mereka akan memperbaiki awalan menjadi "SHA1 (stdin) =" agar konsisten dengan input file.

Saya tidak percaya mereka mengubah ini! Saya bertanya-tanya berapa banyak skrip yang rusak.

Peretas Jahat
sumber
4
Ini hanya akan menghasilkan 20-30 oktet per baris (atau 40-60 karakter). Untuk SHA-256 checksum, ini terkadang tidak cukup. Gunakan -c 256opsi untuk memperpanjangnya hingga 256 oktet per baris.
Rockallite
16

Saya mengamati perilaku ini di bawah OpenSSL 1.0.0e pada Ubuntu 11.10, sedangkan OpenSSL 0.9.8k dan 0.9.8t hanya keluaran hash. Baris perintah OpenSSL tidak dirancang untuk menjadi fleksibel, ini lebih merupakan cara cepat dan kotor untuk melakukan perhitungan kriptografi dari baris perintah.

Jika Anda ingin menggunakan OpenSSL, filter output:

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

Di Linux (dengan alat GNU atau BusyBox), Anda dapat menggunakan sha1sum, yang tidak memerlukan OpenSSL untuk diinstal dan memiliki format output yang stabil. Itu selalu mencetak nama file, jadi cabut itu.

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

Pada sistem BSD termasuk OSX, Anda dapat menggunakan sha1.

echo -n "foo" | sha1 -q

Semua ini menghasilkan checksum dalam heksadesimal diikuti oleh baris baru. Teks di bawah sistem unix selalu terdiri dari urutan garis, dan setiap baris berakhir dengan karakter baris baru. Jika Anda menyimpan output dari perintah dalam variabel shell, baris akhir terakhir dilucuti.

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

Jika Anda perlu menyalurkan input ke program yang membutuhkan checksum tanpa baris akhir final (yang sangat jarang), lepas jalur baru.

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //' | tr -d '\n' | unusual_program
Gilles 'SANGAT berhenti menjadi jahat'
sumber
ini adalah situasi yang sempurna => salin & tempel peta solusi. Terima kasih!
Oberstet
6

Berikut alternatif lain:

echo -n "foo" | openssl sha1 | awk '{print $2}'
Wisnu Kumar
sumber
1
Saya tahu pertanyaannya diajukan dengan format khusus ini, namun, jika seseorang mencoba memperluas ini untuk memasukkan nama file, itu bisa pecah jika nama file memiliki spasi di dalamnya. Hanya kepala untuk orang lain yang mendarat di sini.
Cameron Gagnon
2

Berikut cara untuk melakukannya menggunakan bash built-in alih-alih pipa, awk, sed, tr, cut, dll:

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