“Openssl dgst -sha1” produzindo um prefixo estranho “(stdin) =” e nova linha final


31

Se você executar este comando no seu Unix

echo -n "foo" | openssl dgst -sha1

Você obterá esta saída:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(seguido por uma nova linha).

Como forçar o openssl a não mostrar o (stdin)=prefixo e evitar a nova linha à direita?


@MarkDavidson Hmm, interessante. Tem certeza de que ele nem acrescenta uma nova linha?

Respostas:


22

O formato binário bruto não adiciona nenhuma saída estranha.
Saída como binária e depois converta para hex:

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

Vai lhe dar o seguinte:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

Esse método deve ser à prova de futuro caso alguém decida alterar o formato de saída de texto novamente. Eu tenho certeza que eles irão corrigir o prefixo como "SHA1 (stdin) =" para ser consistente com o de uma entrada de arquivo.

Não acredito que eles mudaram isso! Gostaria de saber quantos scripts foram quebrados.


4
Ele produzirá apenas 20 a 30 octetos por linha (ou 40 a 60 caracteres). Para a soma de verificação SHA-256, isso às vezes não é suficiente. Use a -c 256opção para estendê-lo para 256 octetos por linha.
Rockallite 17/01

16

Eu observo esse comportamento no OpenSSL 1.0.0e no Ubuntu 11.10, enquanto o OpenSSL 0.9.8k e 0.9.8t produzem apenas o hash. A linha de comando do OpenSSL não foi projetada para ser flexível, é uma maneira rápida e suja de executar cálculos criptográficos a partir da linha de comando.

Se você deseja usar o OpenSSL, filtre a saída:

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

No Linux (com ferramentas GNU ou BusyBox), você pode usar sha1sum, o que não requer a instalação do OpenSSL e possui um formato de saída estável. Ele sempre imprime um nome de arquivo, portanto retire-o.

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

Nos sistemas BSD, incluindo OSX, você pode usar sha1.

echo -n "foo" | sha1 -q

Tudo isso gera a soma de verificação em hexadecimal, seguida por uma nova linha. O texto em sistemas unix sempre consiste em uma sequência de linhas e cada linha termina com um caractere de nova linha. Se você armazenar a saída do comando em uma variável de shell, a nova linha final será retirada.

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

Se você precisar canalizar a entrada em um programa que exija uma soma de verificação sem nova linha final (o que é realmente raro), retire a nova linha.

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

esta é a situação perfeita => copiar e colar o mapa da solução. obrigado!
oberstet

6

Aqui está outra alternativa:

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

11
Eu sei que a pergunta é feita com esse formato específico, no entanto, se alguém tentar estender isso para incluir nomes de arquivos, poderá ser interrompido se o nome do arquivo tiver espaços. Apenas um aviso para outras pessoas que pousam aqui.
precisa saber é o seguinte

2

Aqui está uma maneira de fazer isso usando bash built-ins em vez de pipes, awk, sed, tr, cut, etc:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.