Cấm openssl dgst -sha1 Giao dịch sản xuất một ngoại lai (stdin) = Tiền tố và dòng mới


31

Nếu bạn chạy lệnh này trên Unix của bạn

echo -n "foo" | openssl dgst -sha1

Bạn sẽ nhận được đầu ra này:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(tiếp theo là một dòng mới).

Làm cách nào tôi có thể buộc openssl không hiển thị (stdin)=tiền tố và tránh dòng mới theo dõi?


@MarkDavidson Hmm, thú vị. Bạn có chắc chắn rằng nó thậm chí không nối thêm một dòng mới?

Câu trả lời:


22

Định dạng nhị phân thô không thêm bất kỳ đầu ra bên ngoài.
Đầu ra dưới dạng nhị phân sau đó chuyển đổi thành hex:

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

Sẽ cung cấp cho bạn điều này:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Phương pháp này phải là bằng chứng trong tương lai trong trường hợp ai đó quyết định thay đổi định dạng đầu ra văn bản một lần nữa. Tôi chắc chắn họ sẽ sửa tiền tố thành "SHA1 (stdin) =" để phù hợp với đầu vào của tệp.

Tôi không thể tin rằng họ đã thay đổi điều này! Tôi tự hỏi có bao nhiêu kịch bản đã bị hỏng.


4
Nó sẽ chỉ xuất 20-30 octet trên mỗi dòng (hoặc 40-60 ký tự). Đối với tổng kiểm tra SHA-256, điều này đôi khi không đủ. Sử dụng -c 256tùy chọn để mở rộng nó lên 256 octet trên mỗi dòng.
Rockallite

16

Tôi quan sát hành vi này trong OpenSSL 1.0.0e trên Ubuntu 11.10, trong khi OpenSSL 0.9.8k và 0.9.8t chỉ xuất ra hàm băm. Dòng lệnh của OpenSSL không được thiết kế để linh hoạt, đó là một cách nhanh chóng và bẩn thỉu để thực hiện các phép tính mật mã từ dòng lệnh.

Nếu bạn muốn sử dụng OpenSSL, hãy lọc đầu ra:

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

Trên Linux (với các công cụ GNU hoặc BusyBox), bạn có thể sử dụng sha1sum, không yêu cầu OpenSSL phải được cài đặt và có định dạng đầu ra ổn định. Nó luôn in một tên tập tin, vì vậy hãy loại bỏ nó.

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

Trên các hệ thống BSD bao gồm OSX, bạn có thể sử dụng sha1.

echo -n "foo" | sha1 -q

Tất cả những đầu ra này tổng kiểm tra theo hệ thập lục phân theo sau là một dòng mới. Văn bản trong các hệ thống unix luôn bao gồm một chuỗi các dòng và mỗi dòng kết thúc bằng một ký tự dòng mới. Nếu bạn lưu trữ đầu ra của lệnh trong một biến shell, dòng mới cuối cùng sẽ bị loại bỏ.

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

Nếu bạn cần chuyển đầu vào vào một chương trình yêu cầu tổng kiểm tra không có dòng mới cuối cùng (điều này thực sự hiếm), hãy loại bỏ dòng mới.

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

đây là tình huống hoàn hảo => sao chép và dán bản đồ giải pháp. cảm ơn!
oberstet

6

Đây là một lựa chọn khác:

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

1
Tôi biết câu hỏi hỏi với định dạng cụ thể này, tuy nhiên, nếu ai đó cố gắng mở rộng tên này để bao gồm tên tệp, nó có thể bị hỏng nếu tên tệp có khoảng trắng trong đó. Chỉ cần một đầu lên cho những người khác hạ cánh ở đây.
Cameron Gagnon

2

Đây là một cách để làm điều đó bằng cách sử dụng bash tích hợp thay vì ống, awk, sed, tr, cut, v.v.

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.