将pem键转换为ssh-rsa格式

时间:2009-06-18 08:53:28

标签: openssl openssh

我有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

9 个答案:

答案 0 :(得分:113)

无需编译内容。您可以使用ssh-keygen

执行相同的操作
ssh-keygen -f pub1key.pub -i

将从pub1key.pub读取openssl格式的公钥,并以OpenSSH格式输出。

注意:在某些情况下,您需要指定输入格式:

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

来自ssh-keygen docs(来自man ssh-keygen):

  

-m key_format 指定-i(导入)或-e(导出)转换选项的密钥格式。支持的密钥格式为:“RFC4716”(RFC 4716 / SSH2公钥或私钥),“PKCS8”(PEM PKCS8公钥)或“PEM”(PEM公钥)。默认转换格式为“RFC4716”。

答案 1 :(得分:44)

不需要脚本或其他“技巧”:opensslssh-keygen就足够了。我假设密码没有密码(这很糟糕)。

生成RSA对

以下所有方法都以相同的格式提供RSA密钥对

  1. 使用openssl(man genrsa

    openssl genrsa -out dummy-genrsa.pem 2048
    

    genrsa的OpenSSL v1.0.1 genpkey is superseded中,这是执行此操作的新方法(man 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"
    
  3. 将DER转换为PEM

    如果您有DER格式的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对

    中提取公钥
      PEM格式的
    1. openssl rsa -in dummy-xxx.pem -pubout
      
    2. 采用OpenSSH v2格式see

      ssh-keygen -y -f dummy-xxx.pem
      
    3. 注释

      操作系统和软件版本:

      [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
      

      参考文献:

答案 2 :(得分:23)

要回答我自己的问题,在openssl邮件列表上发帖后得到了这个:

这是从OpenSSL公钥转换为OpenSSH公钥的C代码。 您可以从this link获取代码并自行编译:

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

答案 3 :(得分:9)

所有错误的答案。这是正确的:

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

答案 4 :(得分:7)

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

答案 5 :(得分:6)

我做了

  

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

Credit goes here

答案 6 :(得分:2)

以下脚本将获取base64编码的DER格式的ci.jenkins-ci.org公钥证书,并将其转换为OpenSSH公钥文件。这段代码假设使用了一个2048位的RSA密钥,并从这个Ian Boyd的answer中汲取了很多。我已经在Jenkins wiki中对this article的评论中解释了它的工作原理。

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

答案 7 :(得分:0)

FWIW,此BASH脚本将采用PEM或DER格式的X.509证书或OpenSSL公共密钥文件(也为PEM格式)作为第一个参数,并对OpenSSH RSA公共密钥进行分类。这扩展了@mkalkov上面的答案。要求是// .NET Core Console App while (true) { // Get the next message from the Queue. The Queue is a database table that contains a list of "things that need to be done". // Spawn a Task to handle that message. Send the Task all the data it requires to complete. Generally speaking, the Task will collate all the data in an object and make a call (PUT, POST, DELETE) against a set of RESTful web services. // Sleep for some time. Thread.Sleep(sleepTimeInSeconds * 1000); } catgreptrddxxdsedxargsfileuuidgenbase64(1.0+),当然还有openssl。除了bash(包含openssl)以外的所有其他文件,几乎可以保证是任何现代Linux系统上基本安装的一部分,但也许base64(Fedora在xxd中显示了除外)包)。如果有人想清理它并使它变得更好,请告诫。

vim-common

答案 8 :(得分:0)

只需使用:

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

脚本为here