Assinatura digital com openssl

1

Estou tentando assinar e verificar uma assinatura usando um par de chaves RSA.

Veja como eu gero o par de chaves (que funciona bem para criptografia / descriptografia):

ssh-keygen -t rsa -f mykey -N '' -b 2048
mv mykey mykey-priv.pem
ssh-keygen -f mykey.pub -e -m pem > mykey-pub.pem ; rm -f mykey.pub

No entanto, quando tento criptografar um hash (usando a chave privada) e depois verificá-lo (usando a chave pública), ele falha:

openssl dgst -sha256 /etc/hosts > /tmp/hash 
openssl rsautl -sign -inkey mykey-priv.pem -in /tmp/hash -out /tmp/signature
openssl rsautl -verify -pubin -inkey mykey-pub.pem -in /tmp/signature

A última linha me dá não é possível carregar a chave pública

O que eu sinto falta?

Caso seja relevante, estou usando o CentOS 3.9 (antigo e antigo, mas não tenho escolha aqui).

Por fim, aqui está um exemplo de par de chaves:

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA8nVhTRuinf4bGAda1ufF+VGG6f8kIFGt8/oCK74n9E6lXgpu
7KqeRzadaiONDh8GgQXn5bX9O2vOL+sL0xYa3W13eCoT7+4U51C/+8HqBxujRAVm
i4r/Ju+52kober+GSuIfoNF2nMA24EDy9tid0JgHcBJ0NTyhv6sPvNfcFR1Flbpo
LixTGCcn5S9A9NzJXiOkZ6abnxmyEmZsEaboowMay027GLWAw186GODbrGBByhjq
W6W6jcijb7EFdIYCEqtC6RsZmAiuPBK0LfW5078GE05oIZrG8GtQR8f7k8HDpEDF
+ZI53CZiLhrcXq6+tS4U57FqQs8ytUf6Gno7JwIDAQABAoIBAQCn7zd64gZLqmJ3
zThVG+obGyX4U3lhTVHQaD0ysR4ZcJPHxDA6ip7gsmprxr3/puupWD7b86a3jp8c
v4/MIEZxUk3qlDKFAAHIijy/kvuW+sSl65uwUZETFf5DvQq1hYzttxuzFwIx5kzc
HQBsi3MbtQGJ1a5Z5WofSMu4wEa289tAjHQiaXs8WEbgOctwS11lhFbDLwLagBFz
FL+J0C0oGjgNYaLJUihZKsMHCPZ0/LVFDcCus0ep7mQmvAEQ3FhSNNVakUL07XmM
MC6PTUxUvQa8vGDlRnXwGlIWVFNevvudvZjs02J7KWc3hUH9DqXiEm7cClJfoISB
HIq4WFvpAoGBAP0UHfCRyv4/2nZmizX05NG/qMNuz97G6Rir2ltw9wmrpvqK/n4r
d1JX19ECCx2nQM04C4Q7jQMmyqpF21Wf903PrGXPBa8j5XIDJy+YPC2RrifGsaHm
wN1EmYVfYZCphwmTIO2D05n/4Zkgze/KmhMnqpWn27De+LLfgcxsbET7AoGBAPVB
4RvpQCfKdP+ieKRopDE0v+UkdQCogdUz0rhwAdwzhXmUZIJ/Xb4a15DIN+zxKz2h
aiIJFkifKw5bQQQQjiIuRN73YpjQ6D9jWTdEs3E1zaWYFNPNAYqSi/1g/udgLL0N
RAOw5aNCDyOV4OZRESa9rhUUngfK4VrbqWIm1pLFAoGBAOBGWZn9uaTDNXjDuw6f
7b+rV4WJyBEmuR8x/JoYa/RX9+wEDTAGmQGR8yG3693lgFndFueiVn66e9OVgKBK
2MBOD/tRETp6VzVIcguNn5bKiUmanYRamAP+bQZy1mV6tr7XcdDKiFTrHCO1nIqq
QwxClLt3PAtsLX1m8QIV+4TNAoGBAMA161hWi2Mj9mHKUUZ4hAXUU3ggBFqJtYcD
4GeP0MVk03yfYc4sR6mPm9XqNHpL4BmjAWy/Nmmf5LyRo/itiNcc7/jWZL1jLEFR
eUApZYCaLBtVfy0nA8g4ZeIkPGHVK/rWBLHn13EFepvnAKVAb3KvQVlgGSH+THNK
qAs2aQAJAoGAabSXLpXsZTdy1lMUtZlvUhH4tLVgHFJGILMQ3bh2TTMnkaVbPFyy
KDeK+QJGaqjTx1SIXYgANR5cYI1xNge6aVA6T2aY2Dlq3qpAOK3sJWhEZYDxJKeq
Oy97h96/n14jdfh1U4TValcZfgVXqAfBMjxx0fPtSQjIn2RVjZRBpFs=
-----END RSA PRIVATE KEY-----


-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA8nVhTRuinf4bGAda1ufF+VGG6f8kIFGt8/oCK74n9E6lXgpu7Kqe
RzadaiONDh8GgQXn5bX9O2vOL+sL0xYa3W13eCoT7+4U51C/+8HqBxujRAVmi4r/
Ju+52kober+GSuIfoNF2nMA24EDy9tid0JgHcBJ0NTyhv6sPvNfcFR1FlbpoLixT
GCcn5S9A9NzJXiOkZ6abnxmyEmZsEaboowMay027GLWAw186GODbrGBByhjqW6W6
jcijb7EFdIYCEqtC6RsZmAiuPBK0LfW5078GE05oIZrG8GtQR8f7k8HDpEDF+ZI5
3CZiLhrcXq6+tS4U57FqQs8ytUf6Gno7JwIDAQAB
-----END RSA PUBLIC KEY-----
    
por user208115 20.05.2016 / 03:16

1 resposta

5

Além de: ssh-keygen -m é apenas em versões bastante recentes do OpenSSH, muito mais recentes do que eu esperaria no CentOS 3.9. Você usou algum repositório secundário ou construiu você mesmo ou algo assim? Enfim ...

O que o OpenSSH chama de 'PEM' não é o tipo de PEM OpenSSL usa aqui.

Antecedentes: A OpenSSL library há muito tempo suporta dois tipos de estruturas de chave pública, nos formatos PEM e DER:

  • uma estrutura 'herdada' específica para cada algoritmo suportado, com cabeçalhos PEM como -----BEGIN RSA PUBLIC KEY-----
    -----BEGIN DSA PUBLIC KEY-----
    -----BEGIN EC PUBLIC KEY-----
    implementado pelas rotinas PEM_{write,read}{RSA,DSA,EC}PublicKey

  • uma estrutura genérica definida por X.509 denominada SubjectPublicKeyInfo com cabeçalho PEM em -----BEGIN PUBLIC KEY----- !! note que nenhum nome de algoritmo
    implementado pelas rotinas PEM_{write,read}{,RSA,DSA,EC}PUBKEY

No entanto, a linha de comando OpenSSL usa o último quase que exclusivamente, incluindo rsautl -pubin . Você pode ver que você tem o primeiro. Por quê?

OpenSSH , quando recentemente adicionou a opção -m format a ssh-keygen -e export, inexplicavelmente chamada de estruturas herdadas do OpenSSL PEM , mas a estrutura genérica do OpenSSL X.509 PKCS8 - embora não seja de todo PKCS # 8, que é um formato padrão e comum para chaves privadas .

Suas opções são:

  • use a opção de formato de aparência errada, mas realmente correta ssh-keygen -e -m pkcs8

  • converta o arquivo que você usa com a única operação que faz manipula a estrutura legada:
    openssl rsa -in sshpub_called_pem -RSAPublicKey_in -out goodpub -pubout
    mas apenas no OpenSSL 1.0.0 e superior.

  • dado que seu arquivo de chave privada OpenSSH está no formato compatível com OpenSSL ( -----BEGIN RSA PRIVATE KEY----- não -----BEGIN OPENSSH PRIVATE KEY----- , que também é uma adição recente ao OpenSSH), é possível usar OpenSSL em vez de ssh-keygen -e : openssl rsa -in sshprivate -pubout -out pubforopenssl
    ou em 1.0.0 e acima, a nova alternativa brilhante openssl pkey -in sshprivate -pubout -out pubforopenssl

TAMBÉM SEJA PRECISADO : rsautl -sign|-verify (por padrão) usa preenchimento PKCS # 1-v1.5 (também conhecido como tipo 01), mas NÃO obedece ao padrão que requer você também codifica o hash em um ASN.1 SEQUENCE . As assinaturas que você criar dessa maneira NÃO serão verificadas em outro software que obedeça ao padrão, e as assinaturas criadas em outro software fornecerão resultados diferentes (embora PARTICULARMENTE). Considere, em vez disso, usar

 openssl {dgst -hashname | hashname} {-sign privatekey | -verify publickey}

que faz a operação completa: codificar os dados, codificar ASN.1, bloco e sinal RSA ou, por outro lado, verificar, desmarcar, decodificar e corresponder o RSA; ou

 openssl pkeyutl -sign|-verify -inkey key [-pubin] -pkeyopt digest:hashname

em que a chave é uma chave RSA, que faz todo o PKCS # 1-v1.5 exceto codificar os dados. Por exemplo: link
link
link
link
link

    
por 20.05.2016 / 06:50