Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

If you run this command on your Unix

echo -n "foo" | openssl dgst -sha1

You will get this output:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(followed by a newline).

How can I force openssl to not show the (stdin)= prefix, and avoid the trailing newline?

share|improve this question

migrated from security.stackexchange.com Jul 11 '12 at 10:29

This question came from our site for Information security professionals.

    
@MarkDavidson Hmm, interesting. Are you sure it doesn't even append a newline? –  SecurityClown Jul 10 '12 at 18:41

4 Answers 4

I observe this behavior under OpenSSL 1.0.0e on Ubuntu 11.10, whereas OpenSSL 0.9.8k and 0.9.8t output just the hash. OpenSSL's command line is not designed to be flexible, it's more of a quick-and-dirty way to perform cryptographic calculations from the command line.

If you want to use OpenSSL, filter the output:

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

On Linux (with GNU tools or BusyBox), you can use sha1sum, which doesn't require OpenSSL to be installed and has a stable output format. It always prints a file name, so strip that off.

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

On BSD systems including OSX, you can use sha1.

echo -n "foo" | sha1 -q

All of these output the checksum in hexadecimal followed by a newline. Text under unix systems always consists of a sequence of lines, and each line ends with a newline character. If you store the output of the command in a shell variable, the final newline is stripped off.

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

If you need to pipe the input into a program that requires a checksum with no final newline (which is really rare), strip off the newline.

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

Here's another alternative:

echo -n "foo" | openssl sha1 | awk '{print $2}'
share|improve this answer

Here's a way to do it using bash built-ins instead of pipes, awk, sed, tr, cut, etc:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
share|improve this answer

Raw binary format does not add any extraneous output.
Output as binary then convert to hex:

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

Will give you this:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

This method should be future-proof in case someone decides to change the textual output format again. I'm sure they will fix the prefix to be "SHA1(stdin)= " to be consistent with that of a file input.

I can't believe that they changed this! I wonder how many scripts were broken.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.