É possível assinar um arquivo usando uma chave ssh?

33

Eu uso o SSH (OpenSSH 5.5p1 no Linux, para ser preciso). Eu tenho uma chave, na qual eu tenho uma frase secreta. Eu uso isso para o registro normal em coisas de computadores.

Também posso usá-lo para assinar arquivos?

Pelo que entendi, uma chave SSH é uma chave RSA (ou DSA) e, durante o processo de login do SSH, é usada para assinar mensagens enviadas para o servidor. Então, em princípio e na prática, ele pode ser usado para assinar as coisas - na verdade, esse é o seu único propósito.

Mas, até onde eu posso ver, não há como usar a chave para assinar um arquivo arbitrário (como você faria com o PGP, digamos). Existe alguma maneira de fazer isso?

    
por Tom Anderson 08.07.2011 / 16:08

3 respostas

22

Pode não haver uma maneira de fazer isso apenas com as ferramentas do OpenSSH.

Mas isso pode ser feito facilmente com as ferramentas OpenSSL. Na verdade, existem pelo menos duas maneiras de fazer isso. Nos exemplos abaixo, ~/.ssh/id_rsa é sua chave privada.

Uma maneira é usar dgst :

openssl dgst -sign ~/.ssh/id_rsa some-file

O outro está usando pkeyutl :

openssl pkeyutl -sign -inkey ~/.ssh/id_rsa -in some-file

Ambos escrevem uma assinatura binária para a saída padrão. A opção dgst aceita -hex imprime uma representação textual, com alguns detalhes sobre a forma da assinatura. pkeyutl aceita uma opção -hexdump , que é um pouco menos útil. Ambos aceitarão as chaves RSA e DSA. Não tenho idéia do que é o formato da saída. Os dois comandos produzem diferentes formatos. Tenho a impressão de que o pkeyutl é considerado mais moderno do que o dgst .

Para verificar essas assinaturas:

openssl dgst -verify $PUBLIC_KEY_FILE -signature signature-file some-file

e:

openssl pkeyutl -verify -inkey $PUBLIC_KEY_FILE -sigfile signature-file -in some-file

O problema aqui é $PUBLIC_KEY_FILE . O OpenSSL não pode ler o formato de chave pública do OpenSSH, então você não pode simplesmente usar id_rsa.pub . Você tem algumas opções, nenhuma ideal.

Se você tem uma versão do OpenSSH de 5.6 ou posterior, aparentemente você pode fazer isso:

ssh-keygen -e -f ~/.ssh/id_rsa.pub -m pem

O qual gravará a chave pública na saída padrão no formato PEM, que o OpenSSL pode ler.

Se você tem a chave privada, e é uma chave RSA, então você pode extrair a chave pública dela (eu suponho que o arquivo de chave privada codificado por PEM inclua uma cópia da chave pública, uma vez que não é possível derivar a chave pública da própria chave privada) e use isso:

openssl rsa -in ~/.ssh/id_rsa -pubout

Não sei se há um equivalente de DSA. Observe que essa abordagem requer alguma cooperação do proprietário da chave privada, que terá que extrair a chave pública e enviá-la ao verificador em potencial.

Por fim, você pode usar um programa em Python escrito por um sujeito chamado Lars para converter a chave pública do OpenSSH para o formato OpenSSL.

    
por 08.07.2011 / 16:17
9

@ A resposta de Tom ajudou-me a começar, mas não funcionou de imediato.

Esses comandos funcionarão com:

  • OpenSSL 1.0.1 14 de março de 2012
  • OpenSSH_5.9p1

Usando o pkeyutl

# openssl pkeyutl -sign -inkey ~/.ssh/id_sample -in $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl pkeyutl -verify -pubin -inkey pub -in $1 -sigfile $1.sig
Signature Verified Successfully

Usando o dgst

# openssl dgst -sign ~/.ssh/id_sample $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl dgst -verify pub -signature $1.sig $1
Verified OK

A versão pkeyutl só pode assinar arquivos pequenos. Enquanto dgst pode assinar arquivos arbitrariamente grandes, porque é preciso um resumo antes de assinar o resultado.

    
por 02.11.2012 / 22:15
-3

Para verificar essas assinaturas - solução mais fácil:

A maneira mais fácil de garantir que um documento assinado é o mesmo, é gerar novamente o arquivo de assinatura digital e, em seguida, usar o diff para verificar se os dois arquivos de assinatura são os mesmos.

    
por 20.10.2011 / 15:41