Quais são as chaves aceitas pelo openSSH?

0

A pergunta é simples:

What are the (private) key types and (their specification - format, syntax) accepted by current openSSH?

A resposta vaga "as chaves geradas por ssh-keygen " não é aceita - eu sei disso. Eles são chamados de PEM com esses cabeçalhos (variações RSA, DSA, ECDSA):

-----BEGIN RSA PRIVATE KEY-----

O outro formato está descrito em PROTOCOL.key e é uma extensão por openssh . Ele também é usado como padrão para Ed25519 keys, conforme declarado no manual e (independentemente da frase secreta) marcado com o cabeçalho:

-----BEGIN OPENSSH PRIVATE KEY-----

Também existem legacy RSA1 keys que devem desaparecer hoje com o protocolo SSHv1, mas podem ser identificadas pelo cabeçalho:

SSH PRIVATE KEY FILE FORMAT 1.1

Existe algum outro? Eu estou procurando por uma descrição mais detalhada de outras chaves. Eu não encontrei (até agora) explicitamente especificado em qualquer página de manual nem em qualquer RFC para SSH.

A pergunta de bônus (não é necessário responder, mas eu apreciaria o insight):

What is the reason behind (openssh) decoding every dummy file and asking for a passphrase, even if it does not have the proper header?

Nota de rodapé: A questão foi originalmente publicada em openssh -unix-dev list , mas até agora sem nenhuma resposta, estou tentando essa incrível comunidade, se houver alguém capaz de responder.

    
por Jakuje 23.12.2015 / 19:20

1 resposta

2

TL; DR

Os comentários mais úteis do @forcefsck. Infelizmente ele não preencheu a resposta, então eu não pude conceder a recompensa. Em suma, a resposta é PEM + RSA1 + novo formato openSSH que é descrito na pergunta e o principal problema era com o PEM.

O longo & Bônus

O OpenSSH está usando o analisador do openSSL ( PEM_read_bio_PrivateKey() ), que tem o único valor de retorno para todas as falhas ( NULL ) e, se falhar, o openSSH espera que tenha sido por causa da frase secreta incorreta.

Sem OpenSSL

Eu apenas tentei criar o OpenSSH sem o suporte OpenSSL ( --without-openssl configure option) e o comportamento está "correto":

# ./ssh-add <(echo "")
Error loading key "/dev/fd/63": invalid format

Corrigir com o OpenSSL

A outra coisa é como consertar isso. O puxão vem da função ERR_get_error() e seus amigos, o que deve nos permitir distinguir entre diferentes erros.

Erros incorretos de frase secreta

# ./ssh-add /tmp/rsa
140480353842840:error:0906A068:lib(9):func(106):reason(104):pem_lib.c:457:
Enter passphrase for /tmp/rsa: 
140480353842840:error:06065064:lib(6):func(101):reason(100):evp_enc.c:592:
140480353842840:error:0906A065:lib(9):func(106):reason(101):pem_lib.c:482:

Razões: PEM_R_BAD_PASSWORD_READ , PEM_R_BAD_BASE64_DECODE , PEM_R_BAD_DECRYPT .

Analisar códigos de erro

# ./ssh-add <(echo "")
139656018548376:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:701:Expecting: ANY PRIVATE KEY

ou isto:

140654301202072:error:0906D066:lib(9):func(109):reason(102):pem_lib.c:809:

Razão: PEM_R_NO_START_LINE , PEM_R_BAD_END_LINE , mas pode haver mais possibilidades.

Solução?

Adicionar mais verificações para erros do OpenSSL deve nos dar uma opção para escolher qual erro queremos marcar como erro de "formato" e qual é a "senha incorreta". Isso está localizado na função sshkey_parse_private_pem_fileblob() em sshkey.c na linha em torno de 3800.

unsigned long e = ERR_get_error();
if (ERR_GET_REASON(e) == PEM_R_NO_START_LINE ||
    ERR_GET_REASON(e) == PEM_R_BAD_END_LINE) {
        r = SSH_ERR_INVALID_FORMAT;
} else {
        r = SSH_ERR_KEY_WRONG_PASSPHRASE;
}
    
por 05.01.2016 / 16:19