Programming

pem 키를 ssh-rsa 형식으로 변환

procodes 2020. 7. 3. 22:14
반응형

pem 키를 ssh-rsa 형식으로 변환


der이 명령으로 공개 키를 생성하는 형식 의 인증서가 있습니다 .

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

결과는 다음과 같습니다.

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

이와 같은 공개 키를 어떻게 얻을 수 있습니까? 인증서 또는이 공개 키에서?

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

이것은 다음 명령으로 얻었습니다.

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

컴파일 할 필요가 없습니다. 당신은 다음과 같이 할 수 있습니다 ssh-keygen:

ssh-keygen -f pub1key.pub -i

openssl 형식의 공개 키를 읽고 pub1key.pubOpenSSH 형식으로 출력합니다.

참고 : 경우에 따라 입력 형식을 지정해야합니다.

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

ssh-keygen 문서에서 (man ssh-keygen에서) :

-m key_format -i (가져 오기) 또는 -e (내보내기) 변환 옵션의 키 형식을 지정하십시오. 지원되는 키 형식은 "RFC4716"(RFC 4716 / SSH2 공개 또는 개인 키), "PKCS8"(PEM PKCS8 공개 키) 또는 "PEM"(PEM 공개 키)입니다. 기본 변환 형식은 "RFC4716"입니다.


어떤 스크립트 나 다른 '트릭'의 필요성 : openssl와는 ssh-keygen충분하지 않습니다. 키의 암호가 없다고 가정합니다 (나쁜).

RSA 쌍 생성

다음의 모든 방법은 동일한 형식의 RSA 키 쌍을 제공합니다

  1. openssl 사용 ( man genrsa )

    openssl genrsa -out dummy-genrsa.pem 2048
    

    은 OpenSSL 1.0.1에서 genrsa 대체됩니다 에 의해 genpkey이 그것을 (할 수있는 새로운 방법입니다 그래서 남자 genpkey가 ) :

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

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

DER을 PEM으로 변환

DER 형식의 RSA 키 쌍이있는 경우 아래 형식 변환을 허용하기 위해 RSA 키 쌍을 PEM으로 변환 할 수 있습니다.

세대:

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

변환:

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

PEM 형식의 RSA 쌍에서 공개 키 추출

  1. PEM 형식으로 :

    openssl rsa -in dummy-xxx.pem -pubout
    
  2. OpenSSH v2 형식에서는 다음을 참조하십시오 .

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

노트

OS 및 소프트웨어 버전 :

[user@test1 ~]# 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

참고 문헌 :


내 자신의 질문에 대답하기 위해 openssl 메일 링리스트에 게시 한 후 다음을 얻었습니다.

다음은 OpenSSL 공개 키에서 OpenSSH 공개 키로 변환하는 C 코드입니다. 이 링크 에서 코드를 가져 와서 직접 컴파일 할 수 있습니다 .

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;
}

모든 오답. 이것은 올바른 것입니다 :

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


ssh-keygen -f private.pem -y > public.pub

나는 ~했다

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

신용은 여기에 간다


The following script would obtain the ci.jenkins-ci.org public key certificate in base64-encoded DER format and convert it to an OpenSSH public key file. This code assumes that a 2048-bit RSA key is used and draws a lot from this Ian Boyd's answer. I've explained a bit more how it works in comments to this article in Jenkins wiki.

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

Just use:

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

Script is here.


FWIW, this BASH script will take a PEM- or DER-format X.509 certificate or OpenSSL public key file (also PEM format) as the first argument and disgorge an OpenSSH RSA public key. This expands upon @mkalkov's answer above. Requirements are cat, grep, tr, dd, xxd, sed, xargs, file, uuidgen, base64, openssl (1.0+), and of course bash. All except openssl (contains base64) are pretty much guaranteed to be part of the base install on any modern Linux system, except maybe xxd (which Fedora shows in the vim-common package). If anyone wants to clean it up and make it nicer, caveat lector.

#!/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

참고URL : https://stackoverflow.com/questions/1011572/convert-pem-key-to-ssh-rsa-format

반응형