سؤال

لدي شهادة في 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
هل كانت مفيدة؟

المحلول 3

لإجابة على سؤالي الخاص، بعد نشرها على القائمة البريدية بينسل حصلت على هذا:

وهنا هو رمز 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:

ssh-keygen -f pub1key.pub -i

سوف يقرأ المفتاح العام بتنسيق opensl من pub1key.pub وإخراجها بتنسيق OpenSSH.

ملحوظة:في بعض الحالات، ستحتاج إلى تحديد تنسيق الإدخال:

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

من مستندات ssh-keygen (من man ssh-keygen ):

key_format حدد تنسيقًا رئيسيًا لخيارات التحويل -i (استيراد) أو -e (تصدير).التنسيقات الرئيسية المدعومة هي:"RFC4716" (RFC 4716/SSH2 مفتاح عام أو خاص)، "PKCS8" (مفتاح PEM PKCS8 العام) أو "PEM" (مفتاح PEM العام).تنسيق التحويل الافتراضي هو "RFC4716".

لا حاجة للنصوص البرمجية أو "الحيل" الأخرى: openssl و ssh-keygen كافية.أفترض عدم وجود كلمة مرور للمفاتيح (وهو أمر سيء).

إنشاء زوج RSA

توفر كافة الطرق التالية زوج مفاتيح RSA بنفس التنسيق

  1. مع opensl (رجل جنسا)

    openssl genrsa -out dummy-genrsa.pem 2048
    

    في OpenSSL v1.0.1 genrsa تم استبداله بواسطة genpkey إذن هذه هي الطريقة الجديدة للقيام بذلك (رجل جينبكي):

    openssl genpkey -algorithm RSA -out dummy-genpkey.pem -pkeyopt rsa_keygen_bits:2048
    
  2. مع سش كجن

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

تحويل DER إلى PEM

إذا كان لديك زوج مفاتيح RSA بتنسيق DER، فقد ترغب في تحويله إلى 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

قم باستخراج المفتاح العام من زوج RSA بتنسيق PEM

  1. بتنسيق بيم:

    openssl rsa -in dummy-xxx.pem -pubout
    
  2. بتنسيق OpenSSH v2 يرى:

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

ملحوظات

إصدار نظام التشغيل والبرنامج:

[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

مراجع:

وجميع الإجابات خاطئة. هذا هو الصحيح:

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

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

فعلت مع

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

الائتمان يذهب هنا

والنص التالي أن الحصول على شهادة المفتاح العمومي ci.jenkins-ci.org في شكل DER ترميز base64 في وتحويله إلى ملف المفتاح العام المفتوح. يفترض هذا الرمز أنه يتم استخدام مفتاح RSA 2048 بت وتوجه الكثير من <أ href على هذا إيان بويد = "https://stackoverflow.com/questions/1193529/how-to-store-retreieve-rsa-public-private -مفتاح / 13104466 # 13104466 "> الجواب . لقد شرحت أكثر قليلا كيف يعمل في تصريحات لل هذه المادة في جنكينز ويكي.

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

وFWIW، وهذا السيناريو BASH تأخذ شهادة PEM- أو DER تنسيق X.509 أو بينسل ملف مفتاح العام (أيضا تنسيق PEM) كما الوسيطة الأولى وتقيأ على المفتاح العمومي المفتوح RSA. هذا يوسع عليه الجواب @ mkalkov في أعلاه. المتطلبات هي cat، grep، tr، dd، xxd، sed، xargs، file، uuidgen، base64، openssl (1.0+)، وبالطبع bash. كل ما عدا openssl (يحتوي على base64) مضمونة الى حد كبير أن أكون جزءا من قاعدة تثبيت على أي نظام لينكس الحديثة، ربما باستثناء xxd (مما يدل على فيدورا في حزمة vim-common). إذا أراد أي شخص لتنظيفه وجعله أجمل، قارئا التحذير.

#!/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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top