
Gerei uma chave privada usando libressl 3.0 usando curve secp521r1
.
openssl genpkey -aes128 -algorithm EC -pkeyopt ec_paramgen_curve:secp521r1 -pkeyopt ec_param_enc:named_curve
Pelo que eu sei, essa curva é a mesma que o ssh-keygen usa com ssh-keygen -t ecdsa -b 521
e da documentação que sei que o ssh-keygen agora usa aes128 para criptografar a chave privada.
O tamanho da chave privada libressl é 534
e o tamanho da chave ssh-keygen é 736
.
Minha pergunta é: o que o ssh-keygen faz extra para aumentar o tamanho da chave?
Além disso: ambos são trocáveis? uma chave privada gerada em uma pode ser convertida na outra?
Responder1
TLDR: existem muitos formatos diferentes para arquivos de chave privada
E depende em parte da versão do OpenSSH, que você não forneceu.
Historicamente, exceto para a versão 1 do protocolo obsoleto (e o tipo de chave 'rsa1'), o OpenSSH usou (a parte libcrypto do) OpenSSL para fazer a maioria de suas operações criptográficas - incluindo o armazenamento de chaves privadas (ou, na verdade, pares de chaves) em arquivos, usando oformatos 'tradicionais' ou 'legados' definidos por SSLeay/OpenSSL. OpenSSL também suporta 'novos' (desde 1998!) Formatos PKCS8, que são (um pouco) mais seguros. Existem, portanto, 4 formatos PEM suportados pelo OpenSSL para "ECDSA" (mais exatamente Weierstrass EC estilo X9 que cobre X9.62 ECDSA e X9.63 ECDH) dos quais OpenSSHgeraapenas 2, mas (usando libcrypto) podem ler todos. Quando ssh-keygen
criptografaFormato OpenSSLarquivos, versões recentes usam AES-128-CBC, mas isso nem sempre foi verdade.
Começando com a versão 6.5 em 2014-01,OpenSSH adicionou seu próprio ‘novo’ formato de arquivo, em parte para fornecer melhor segurança do que os formatos legados do OpenSSL (quando criptografados) e em parte para oferecer suporte ao então novo algoritmo Ed25519, que o OpenSSL não suportava de forma alguma. ssh-keygen
tinha a opção -o
de solicitar um novo formato para qualquer tipo de chave diferente de ed25519 (ou rsa1), e você encontrará muitos Stack Qs e As dos últimos anos fazendo referência e geralmente recomendando essa opção. Os arquivos de formato 'novo' são criptografados com AES256-CBC por padrão, que pode ser substituído por -Z ciphername
, mas a página de manual aparentemente não foi atualizada para nenhum deles. A partir da versão 7.8 em 2018-08, o OpenSSH agora usa como padrão o formato 'novo' para todos os tipos de chave, embora você possa usar -m pem
para solicitar o formato OpenSSL para qualquer coisa diferente de ed25519. Se você verificar man ssh-keygen
seu sistema (a menos que seja Windows), ele deverá descrever um desses casos, provavelmente o último.
(Há também o formato PKCS12, também conhecido como PFX, que OpenSSLpodeusado para uma chave privada, mas normalmente é usado apenas para combinar uma chave privada (ou várias) com um ou mais certificados X.509 para essa(s) chave(s), o que é uma situação diferente e não aplicável ao SSH, que nunca usa certificados X.509. Outros programas ou sistemas usam outros formatos: 'comercial'/Tectia SSH tem seu próprio formato, e PuTTY tem seu próprio formato PPK = PuTTY Private Key. Et cetera, et cetera, Yul Brynner. Todos estes são semanticamente equivalentes e, com ferramentas adequadas, podem ser interconvertidos.)
Todos os formatos de chave privada usados pelo OpenSSH sãoEstilo PEM; os dados binários são codificados em texto como base64 com linhas de cabeçalho e trailer no formato
-----BEGIN (something)-----
(sometimes some headers here)
(data encoded in base64, broken into lines of 64 characters)
-----END (something)-----
então você pode saber qual formato possui apenas olhando para a linha tracejada-BEGIN. Veja quase crossdupeshttps://security.stackexchange.com/questions/39279/stronger-encryption-for-ssh-keysou mais brevementehttps://security.stackexchange.com/questions/129724/how-to-check-if-an-ssh-private-key-has-passphrase-or-notehttps://security.stackexchange.com/questions/200935/how-do-i-determine-if-an-existente-ssh-private-key-is-secure(meu).
As diferenças:o tamanho de 736 caracteres para uma chave ecdsa-p521 corresponde ao novo formato OpenSSHnão criptografado-- você éclarovocê deu uma senha? - e 534 corresponde ao formato criptografado PKCS8 criado pelo OpenSSL 1.0.2, que IIRC é quando o LibreSSL foi bifurcado. (OpenSSL 1.1.0 up altera a criptografia PKCS8 para usar HMAC-SHA256 em PBKDF2, o que torna o arquivo um pouco maior. OpenSSL 1.1.0 up também torna param_enc=named o padrão para que você não precise mais especificá-lo.) O novo OpenSSH O formato é maior que o formato PKCS8-enc principalmente porque, sem motivo óbvio, ele armazena o valor da chave pública (para ECDSA, um ponto de curva no formato X9.62)duas vezes-- uma vez na seção do arquivo especificada para chave pública, ede novona seção especificada para privatekey. Além disso, o formato OpenSSH tem a maioria de seus metadados como strings de texto e todos os campos de comprimento de 4 bytes, enquanto PKCS8 (como os formatos legados OpenSSL) usa ASN.1 com campos de comprimento variável principalmente de apenas 1 byte e metadados em sua maioria binários, especialmente 'OIDs' para os algoritmos usados.)
Além disso: ambos são trocáveis? uma chave privada gerada em uma pode ser convertida na outra?
Sim e não. Como observado, o OpenSSH usando OpenSSL pode ler (mas não escrever) PKCS8, portanto, ssh-keygen
pode convertê-lo para OpenSSH-new fazendo uma alteração nula nele, ou seja, 'alterando' a senha para o valor existente; de 6,5 a 7,7 você deve especificar -o
e de 7,8 em diante é o padrão. Indo para o outro lado, ssh-keygen
pode converter para OpenSSL legado, mas não diretamente para PKCS8, você precisa usar openssl
para fazer isso, explicitamente com pkcs8 -topk8
ou em 1.0.0 acima (que agora deve ser todo mundo, e definitivamente todo LibreSSL) apenas pkey
. (O primeiro padrão é criptografado e o último é não criptografado, mas ambos podem ser substituídos.)