Não é possível assinar com o DSA

0

Uma chave DSA é criada com:

openssl genpkey -genparam -algorithm DSA -out dsaparams.pem -pkeyopt dsa_paramgen_bits:1024

openssl genpkey -paramfile dsaparams.pem -out dsakey.pem

Quando tento assinar, esse erro está sendo exibido:

echo 'bacon' > text

openssl pkeyutl -sign -in text -inkey dsakey.pem -out sig
Public Key operation error

É possível assinar com openssl dgst -sign , mas não com os comandos acima.

Por que isso acontece? O man openssl-pkeyutl diz que o DSA permite assinatura e verificação. Estou usando o OpenSSL 1.1.0g

    
por Sean Walsh 04.10.2018 / 16:02

1 resposta

1

TLDR: parece que openssl pkeyutl foi projetado para assinar um hash, mas é alimentado com um arquivo menor, onde o hash é esperado; e alguns cheques presentes no OpenSSL 1.1.0g (mas não no OpenSSL 1.0.2g) detectam esse erro.

FWIW, não houve erro quando tentei os comandos da pergunta com o OpenSSL 1.0.2g. Mas vejo três razões pelas quais isso poderia falhar (e, para o primeiro, deveria):

  1. openssl pkeyutl está documentado para não executar um hash, que deve ser feito externamente. Então, meu palpite é que versões mais recentes do openssl pkeyutl bark falham bem quando o arquivo de entrada é menor que o parâmetro q da chave privada, porque essa é a única coisa boa Faz. Isso é pelo menos consistente com a página do manual :

    In case of RSA, ECDSA and DSA signatures, this utility will not perform hashing on input data but rather use the data directly as input of signature algorithm. Depending on key type, signature type and mode of padding, the maximum acceptable lengths of input data differ. In general, with RSA the signed data can't be longer than the key modulus, in case of ECDSA and DSA the data shouldn't be longer than field size, otherwise it will be silently truncated to field size.

    In other words, if the value of digest is sha1 the input should be 20 bytes long binary encoding of SHA-1 hash function output.

  2. Atualmente, o DSA de 1024 bits está, com razão, obsoleto e, em alguns locais (incluindo algumas implementações de SSH), o suporte a ele foi sumariamente removido.

  3. Hoje em dia, o SHA-1 é corretamente suspenso.

Eu sugeriria pelo menos 2048 bits de DSA, SHA-256 e hashing do arquivo antes de computar a assinatura, o que é feito melhor com openssl dgst , o que pode significar quando openssl pkeyutl não pode. Eu não sou um guru openssl, mas eu tentaria investigar o seguinte:

# generate a private key and extract the public key
openssl genpkey -paramfile dsaparams.pem -out dsaprivkey.pem
openssl dsa -in dsaprivkey.pem -pubout > dsapubkey.pem

# create a file "myfile" to be signed
echo 'The Magic Words are Squeamish Ossifrage' > myfile

# create signature "myfile.sig"
openssl dgst -sha256 -sign dsaprivkey.pem myfile > myfile.sig

# verify "myfile" against signature "myfile.sig" and public key
openssl dgst -sha256 -verify dsapubkey.pem -signature myfile.sig myfile

Nota: Uma tentativa anterior tornou o openssl 1.0.2g gerar assinaturas com 160 bits q (talvez usando SHA-1). Por comentário , adicionei -sha256 a openssl dgst , mas não fez diferença. As experiências sugerem que é necessário usar -pkeyopt dsa_paramgen_q_bits:256 , mesmo que a página do manual explique explicitamente -pkeyopt dsa_paramgen_md:sha256 cuida disso:

dsa_paramgen_md:digest
The digest to use during parameter generation. Must be one of sha1, sha224 or sha256. If set, then the number of bits in q will match the output size of the specified digest and the dsa_paramgen_q_bits parameter will be ignored (..)

    
por 04.10.2018 / 16:48