Por que minha impressão digital de chave OpenSSH não corresponde à impressão digital do par de chaves do console do AWS EC2?

73

Quando importo minha chave pública OpenSSH no chaveiro do AWS EC2, a impressão digital mostrada pela AWS não corresponde ao que vejo:

ssh-keygen -l -f my_key

É um comprimento diferente e tem bytes diferentes.

Por quê? Tenho certeza de que carreguei a chave correta.

Craig Ringer
fonte

Respostas:

102

O AWS EC2 mostra a impressão digital SSH2, não a impressão digital OpenSSH que todos esperam. Não diz isso na interface do usuário.

Ele também mostra dois tipos completamente diferentes de impressões digitais, dependendo se a chave foi gerada na AWS e baixada, ou se você carregou sua própria chave pública.

Impressões digitais geradas com

ssh-keygen -l -f id_rsa

será não coincidir com o que mostra EC2. Você pode usar as ferramentas da API da AWS para gerar uma impressão digital com o ec2-fingerprint-keycomando ou usar o OpenSSL para fazer isso.

Observe que, se você gerou uma chave originalmente na AWS, mas depois fez o upload novamente (por exemplo, para outra região), obterá uma impressão digital diferente, pois será necessária a impressão digital SSH2 RSA, em vez do sha1 exibido para as chaves que você gerado na AWS.

Divertido, ei? Esta captura de tela possui duas cópias da mesma chave com impressões digitais diferentes

Acima, test-generatedfoi gerado usando o AWS EC2. test-generated-reuploadedé a chave pública da chave privada gerada pela AWS, extraída ssh-keygen -ye carregada novamente. A terceira chave test-uploaded,, é uma chave gerada localmente ... mas a ssh-keygen -limpressão digital local é b2:2c:86:d6:1e:58:c0:b0:15:97:ab:9b:93:e7:4e:ea.

$ ssh-keygen -l -f theprivatekey
2048 b2:2c:86:d6:1e:58:c0:b0:15:97:ab:9b:93:e7:4e:ea
$ openssl pkey -in theprivatekey -pubout -outform DER | openssl md5 -c
Enter pass phrase for id_landp:
(stdin)= 91:bc:58:1f:ea:5d:51:2d:83:d3:6b:d7:6d:63:06:d2

Chaves geradas localmente

Você pode usar o OpenSSL, como demonstrado por Daniel nos fóruns da AWS , para gerar a impressão digital no formato usado pela AWS para mostrar impressões digitais para chaves públicas carregadas (SSH2 MD5), como:

7a:58:3a:a3:df:ba:a3:09:be:b5:b4:0b:f5:5b:09:a0

Eles podem ser gerados extraindo a parte pública da chave privada e fazendo o hash usando:

openssl pkey -in id_rsa -pubout -outform DER | openssl md5 -c

Chaves geradas na AWS

Se a impressão digital da chave mostrada no console da AWS for mais longa, será uma chave privada gerada na AWS, como:

ea:47:42:52:2c:25:43:76:65:f4:67:76:b9:70:b4:64:12:00:e4:5a

Nesse caso, você precisa usar o seguinte comando, também mostrado por Daniel nos fóruns da AWS, para gerar um hash sha1 com base na chave privada:

openssl pkcs8 -in aws_private.pem -nocrypt -topk8 -outform DER | openssl sha1 -c

no arquivo de certificado / chave privada gerado pela AWS e baixado. Também funcionará nas chaves que você converteu no formato OpenSSH.

Referências

Vejo:

Craig Ringer
fonte
4
Triste a clareza faltando AWS sobre isso, eles estão abrindo um potencial falha de segurança, tornando mais difícil para verificar chaves
Jaime Hablutzel
Ótima resposta! Na inicial sshde comando, com versões mais recentes você precisa de uma opção -E para especificar o formato md5: ssh-keygen -E md5 -l -f id_rsa.
RichVel
14

Se você tiver apenas chaves públicas, poderá gerar a impressão digital da AWS da seguinte maneira:

ssh-keygen -e -f id_rsa.pub -m pkcs8 | openssl pkey -pubin -outform der | openssl md5 -c
J. Doe
fonte
2

Há um recurso nos documentos da AWS http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#verify-key-pair-fingerprints

Se você criou seu par de chaves usando a AWS, poderá usar as ferramentas OpenSSL para gerar uma impressão digital a partir do arquivo de chave privada:

cópia de

$ openssl pkcs8 -in path_to_private_key -inform PEM -outform DER -topk8 -nocrypt | openssl sha1 -c

Se você criou seu par de chaves usando uma ferramenta de terceiros e carregou a chave pública na AWS, poderá usar as ferramentas OpenSSL para gerar uma impressão digital a partir do arquivo de chave privada em sua máquina local:

cópia de

$ openssl rsa -in path_to_private_key -pubout -outform DER | openssl md5 -c

A saída deve corresponder à impressão digital exibida no console.

Goutham
fonte
2

Isto é o que eu uso:

openssl rsa -RSAPublicKey_in -in <(ssh-keygen -f ~/.ssh/id_rsa.pub -e -m PEM) -inform PEM -outform DER 2>/dev/null | openssl md5 -c | awk '{print $2}'

Isso gera a impressão digital da chave pública, semelhante a algumas das opções acima.

Max Murphy
fonte
1

Para aqueles de nós que usam Python

from Crypto.PublicKey import RSA
import hashlib
import base64

#Load your key from disk, or a string, or generate.
my_key = RSA.importKey(open(my_rsa_private_key, 'r').read())

# Normal md5 fingerprint
fp_plain = hashlib.md5(base64.b64decode(my_key.exportKey('OpenSSH').strip().split()[1].encode('ascii'))).hexdigest()
print ':'.join(a+b for a,b in zip(fp_plain[::2], fp_plain[1::2]))

#AWS' EC2 fingerprint
public_only_key = RSA.importKey(my_key.exportKey('OpenSSH'))
fp_plain = hashlib.md5(public_only_key.exportKey('DER')).hexdigest()
print ':'.join(a+b for a,b in zip(fp_plain[::2], fp_plain[1::2]))
Andy
fonte
Infelizmente, isso falhou para mim no macOS 10.11 usando o Homebrew Python 2.7.13 mais recente, com este erro:ValueError: PEM encryption format not supported.
RichVel 7/17
@ RichVel, não consigo reproduzir o erro. Acabei de testar no macOS 10.12 usando o homebrew python 2.7.13 em um virtualenv, e funcionou perfeitamente. Se eu tivesse que adivinhar, talvez alguns dos requisitos de C para o pycrypto não tenham sido atendidos por você. Talvez isso possa ajudar?
Andy
1
#!/bin/bash
key_file=$1
if [[ -n $key_pub_file ]]; then
    ssh-keygen -e -f $key_pub_file -m pkcs8 | openssl pkey -pubin -outform der | openssl md5 -c
else
    echo "pass the pub file as argument"
fi

Aqui está um script que eu uso, adicione o caminho do script para env. Obrigado a J.Doe pela resposta

Sand1512
fonte
0

Java (usando BouncyCastle). Se o console da AWS exibir teclas mais curtas, tente com o MD5. (SHA1: 20 bytes, MD5: 16 bytes).

  /**
   * @return the SHA1 digest of the DER encoded RSA private key, e.g. 16:61:7d:1c:e7:d1:3b:93:b6:81:bf:64:7a:a0:38:fa:b6:6c:9e:e4
   */
  private String getAwsFingerprint(File rsaPrivateKeyFileFromAws) throws Exception {
    try(FileReader reader = new FileReader(rsaPrivateKeyFileFromAws)) {
      java.security.KeyPair keyPair = new JcaPEMKeyConverter().getKeyPair((PEMKeyPair) new PEMParser(reader).readObject());
      String hex = Hex.toHexString(MessageDigest.getInstance("SHA1").digest(keyPair.getPrivate().getEncoded()));
      StringBuilder sb = new StringBuilder();
      for(int i = 0; i < hex.length();) {
        sb.append(hex.charAt(i++));
        sb.append(hex.charAt(i++));
        sb.append(i % 2 == 0 && i != hex.length() ? ":" : "");
      }
      return sb.toString();
    }
  }
Reto Höhener
fonte