it-swarm.com.de

Konvertieren Sie den Pem-Schlüssel in das ssh-rsa-Format

Ich habe ein Zertifikat im der-Format, mit diesem Befehl generiere ich einen öffentlichen Schlüssel:

openssl x509 -inform der -in ejbcacert.cer -noout -pubkey > pub1key.pub

Welche Ergebnisse ergeben sich daraus:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vbqajDw4o6gJy8UtmIbkcpnk
O3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2
eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1
QWPdspTBKcxeFbccDwIDAQAB
-----END PUBLIC KEY-----

Wie kann ich einen öffentlichen Schlüssel wie diesen erhalten? Entweder aus dem Zertifikat oder Aus diesem öffentlichen Schlüssel?

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC7vbqajDw4o6gJy8UtmIbkcpnkO3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1QWPdspTBKcxeFbccDw==

Dies wurde mit diesem Befehl erhalten:

ssh-keygen -y -f private_key1.pem > public_key1.pub
120
Adrya

Um meine eigene Frage zu beantworten, bekam ich nach dem Posten auf der openssl-Mailingliste folgendes:

Hier ist C-Code, der von einem öffentlichen OpenSSL-Schlüssel in einen öffentlichen OpenSSH-Schlüssel konvertiert werden soll ..__ Sie können den Code von diesem Link herunterladen und ihn selbst kompilieren:

static unsigned char pSshHeader[11] = { 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61};

static int SshEncodeBuffer(unsigned char *pEncoding, int bufferLen, unsigned char* pBuffer)
{
   int adjustedLen = bufferLen, index;
   if (*pBuffer & 0x80)
   {
      adjustedLen++;
      pEncoding[4] = 0;
      index = 5;
   }
   else
   {
      index = 4;
   }
   pEncoding[0] = (unsigned char) (adjustedLen >> 24);
   pEncoding[1] = (unsigned char) (adjustedLen >> 16);
   pEncoding[2] = (unsigned char) (adjustedLen >>  8);
   pEncoding[3] = (unsigned char) (adjustedLen      );
   memcpy(&pEncoding[index], pBuffer, bufferLen);
   return index + bufferLen;
}

int main(int argc, char**  argv)
{
   int iRet = 0;
   int nLen = 0, eLen = 0;
   int encodingLength = 0;
   int index = 0;
   unsigned char *nBytes = NULL, *eBytes = NULL;
   unsigned char* pEncoding = NULL;
   FILE* pFile = NULL;
   EVP_PKEY *pPubKey = NULL;
   RSA* pRsa = NULL;
   BIO *bio, *b64;

   ERR_load_crypto_strings(); 
   OpenSSL_add_all_algorithms();

   if (argc != 3)
   {
      printf("usage: %s public_key_file_name ssh_key_description\n", argv[0]);
      iRet = 1;
      goto error;
   }

   pFile = fopen(argv[1], "rt");
   if (!pFile)
   {
      printf("Failed to open the given file\n");
      iRet = 2;
      goto error;
   }

   pPubKey = PEM_read_PUBKEY(pFile, NULL, NULL, NULL);
   if (!pPubKey)
   {
      printf("Unable to decode public key from the given file: %s\n", ERR_error_string(ERR_get_error(), NULL));
      iRet = 3;
      goto error;
   }

   if (EVP_PKEY_type(pPubKey->type) != EVP_PKEY_RSA)
   {
      printf("Only RSA public keys are currently supported\n");
      iRet = 4;
      goto error;
   }

   pRsa = EVP_PKEY_get1_RSA(pPubKey);
   if (!pRsa)
   {
      printf("Failed to get RSA public key : %s\n", ERR_error_string(ERR_get_error(), NULL));
      iRet = 5;
      goto error;
   }

   // reading the modulus
   nLen = BN_num_bytes(pRsa->n);
   nBytes = (unsigned char*) malloc(nLen);
   BN_bn2bin(pRsa->n, nBytes);

   // reading the public exponent
   eLen = BN_num_bytes(pRsa->e);
   eBytes = (unsigned char*) malloc(eLen);
   BN_bn2bin(pRsa->e, eBytes);

   encodingLength = 11 + 4 + eLen + 4 + nLen;
   // correct depending on the MSB of e and N
   if (eBytes[0] & 0x80)
      encodingLength++;
   if (nBytes[0] & 0x80)
      encodingLength++;

   pEncoding = (unsigned char*) malloc(encodingLength);
   memcpy(pEncoding, pSshHeader, 11);

   index = SshEncodeBuffer(&pEncoding[11], eLen, eBytes);
   index = SshEncodeBuffer(&pEncoding[11 + index], nLen, nBytes);

   b64 = BIO_new(BIO_f_base64());
   BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
   bio = BIO_new_fp(stdout, BIO_NOCLOSE);
   BIO_printf(bio, "ssh-rsa ");
   bio = BIO_Push(b64, bio);
   BIO_write(bio, pEncoding, encodingLength);
   BIO_flush(bio);
   bio = BIO_pop(b64);
   BIO_printf(bio, " %s\n", argv[2]);
   BIO_flush(bio);
   BIO_free_all(bio);
   BIO_free(b64);

error:
   if (pFile)
      fclose(pFile);
   if (pRsa)
      RSA_free(pRsa);
   if (pPubKey)
      EVP_PKEY_free(pPubKey);
   if (nBytes)
      free(nBytes);
   if (eBytes)
      free(eBytes);
   if (pEncoding)
      free(pEncoding);

   EVP_cleanup();
   ERR_free_strings();
   return iRet;
}
21
Adrya

Keine Notwendigkeit, Sachen zu kompilieren. Dasselbe können Sie mit ssh-keygen machen:

ssh-keygen -f pub1key.pub -i

liest den öffentlichen Schlüssel im openssl-Format von pub1key.pub und gibt ihn im OpenSSH-Format aus.

Hinweis : In einigen Fällen müssen Sie das Eingabeformat angeben:

ssh-keygen -f pub1key.pub -i -mPKCS8

Aus den ssh-keygen-Dokumenten (Von man ssh-keygen):

-m key_format Geben Sie ein Schlüsselformat für die Konvertierungsoptionen -i (Import) oder -e (Export) an. Die unterstützten Schlüsselformate sind: „RFC4716“ (öffentlicher oder privater Schlüssel RFC 4716/SSH2), „PKCS8“ (öffentlicher PEM PKCS8-Schlüssel) oder „PEM“ (öffentlicher PEM-Schlüssel). Das Standardkonvertierungsformat ist "RFC4716".

108
Victor Mataré

Keine Notwendigkeit für Skripte oder andere "Tricks": openssl und ssh-keygen reichen aus. Ich gehe davon aus, dass kein Passwort für die Schlüssel vorhanden ist (was schlecht ist).

Generieren Sie ein RSA-Paar

Alle folgenden Methoden ergeben ein RSA-Schlüsselpaar im gleichen Format

  1. Mit openssl ( man genrsa )

    openssl genrsa -out dummy-genrsa.pem 2048
    

    In OpenSSL v1.0.1 wird genrsadurch genpkey ersetzt. Dies ist der neue Weg ( man genpkey ):

    openssl genpkey -algorithm RSA -out dummy-genpkey.pem -pkeyopt rsa_keygen_bits:2048
    
  2. Mit ssh-keygen

    ssh-keygen -t rsa -b 2048 -f dummy-ssh-keygen.pem -N '' -C "Test Key"
    

Umwandlung von DER in PEM

Wenn Sie ein RSA-Schlüsselpaar im DER-Format haben, möchten Sie es möglicherweise in PEM konvertieren, um die folgende Formatkonvertierung zu ermöglichen:

Generation:

openssl genpkey -algorithm RSA -out genpkey-dummy.cer -outform DER -pkeyopt rsa_keygen_bits:2048

Umwandlung:

openssl rsa -inform DER -outform PEM -in genpkey-dummy.cer -out dummy-der2pem.pem

Extrahieren Sie den öffentlichen Schlüssel aus dem PEM-formatierten RSA-Paar

  1. im PEM-Format:

    openssl rsa -in dummy-xxx.pem -pubout
    
  2. im OpenSSH v2-Format siehe :

    ssh-keygen -y -f dummy-xxx.pem
    

Anmerkungen

Betriebssystem- und Softwareversion:

[[email protected] ~]# cat /etc/redhat-release ; uname -a ; openssl version
CentOS release 6.5 (Final)
Linux test1.example.local 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
OpenSSL 1.0.1e-fips 11 Feb 2013

Verweise:

39
Thomas

Alle falschen Antworten. Das ist das Richtige:

ssh-keygen -i -m PKCS8 -f public-key.pem

6
Boeboe

Ich habe mit gemacht 

ssh-keygen -i -f $ sshkeysfile >> authorized_keys

Guthaben geht hier

6
periklis
ssh-keygen -f private.pem -y > public.pub
6
zkilnbqi

Das folgende Skript würde das öffentliche Schlüsselzertifikat ci.jenkins-ci.org im Base64-codierten DER-Format abrufen und in eine öffentliche OpenSSH-Schlüsseldatei konvertieren. Bei diesem Code wird davon ausgegangen, dass ein 2048-Bit-RSA-Schlüssel verwendet wird, und er zieht eine Menge von diesem answer von Ian Boyd. In den Kommentaren zu diesem Artikel in Jenkins Wiki habe ich etwas mehr darüber erklärt, wie es funktioniert.

echo -n "ssh-rsa " > jenkins.pub
curl -sfI https://ci.jenkins-ci.org/ | grep X-Instance-Identity | tr -d \\r | cut -d\  -f2 | base64 -d | dd bs=1 skip=32 count=257 status=none | xxd -p -c257 | sed s/^/00000007\ 7373682d727361\ 00000003\ 010001\ 00000101\ / | xxd -p -r | base64 -w0 >> jenkins.pub
echo >> jenkins.pub
2
mkalkov

FWIW, dieses BASH-Skript verwendet ein X.509-Zertifikat im PEM- oder DER-Format oder eine öffentliche OpenSSL-Schlüsseldatei (auch PEM-Format) als erstes Argument und weist einen öffentlichen OpenSSH-RSA-Schlüssel aus. Dies erweitert @ mkalkovs Antwort oben. Voraussetzungen sind cat, grep, tr, dd, xxd, sed, xargs, file, uuidgen, base64, openssl (1.0+) und natürlich bash. Alle, mit Ausnahme von openssl (enthält base64), sind so ziemlich garantiert Teil der Basisinstallation auf jedem modernen Linux-System, außer vielleicht xxd (was Fedora im Paket vim-common zeigt). Wenn jemand es sauberer machen und es schöner machen will, unterlassen Sie es dem Lektor.

#!/bin/bash
#
# Extract a valid SSH format public key from an X509 public certificate.
#

# Variables:
pubFile=$1
fileType="no"
pkEightTypeFile="$pubFile"
tmpFile="/tmp/`uuidgen`-pkEightTypeFile.pk8"

# See if a file was passed:
[ ! -f "$pubFile" ] && echo "Error, bad or no input file $pubFile." && exit 1

# If it is a PEM format X.509 public cert, set $fileType appropriately:
pemCertType="X$(file $pubFile | grep 'PEM certificate')"
[ "$pemCertType" != "X" ] && fileType="PEM"

# If it is an OpenSSL PEM-format PKCS#8-style public key, set $fileType appropriately:
pkEightType="X$(grep -e '-BEGIN PUBLIC KEY-' $pubFile)"
[ "$pkEightType" != "X" ] && fileType="PKCS"

# If this is a file we can't recognise, try to decode a (binary) DER-format X.509 cert:
if [ "$fileType" = "no" ]; then
        openssl x509 -in $pubFile -inform DER -noout
        derResult=$(echo $?)
        [ "$derResult" = "0" ] && fileType="DER"
fi

# Exit if not detected as a file we can use:
[ "$fileType" = "no" ] && echo "Error, input file not of type X.509 public certificate or OpenSSL PKCS#8-style public key (not encrypted)." && exit 1

# Convert the X.509 public cert to an OpenSSL PEM-format PKCS#8-style public key:
if [ "$fileType" = "PEM" -o "$fileType" = "DER" ]; then
        openssl x509 -in $pubFile -inform $fileType -noout -pubkey > $tmpFile
        pkEightTypeFile="$tmpFile"
fi

# Build the string:
# Front matter:
frontString="$(echo -en 'ssh-rsa ')"

# Encoded modulus and exponent, with appropriate pointers:
encodedModulus="$(cat $pkEightTypeFile | grep -v -e "----" | tr -d '\n' | base64 -d | dd bs=1 skip=32 count=257 status=none | xxd -p -c257 | sed s/^/00000007\ 7373682d727361\ 00000003\ 010001\ 00000101\ / | xxd -p -r | base64 -w0 )"

# Add a comment string based on the filename, just to be Nice:
commentString=" $(echo $pubFile | xargs basename | sed -e 's/\.crt\|\.cer\|\.pem\|\.pk8\|\.der//')"

# Give the user a string:
echo $frontString $encodedModulus $commentString

# cleanup:
rm -f $tmpFile
0
db_

Benutz einfach:

ssh-keygen -y -f private_key1.pem > public_key1.pub

Skript ist hier .

0
nicks91