1

I am using the ruby EC2 SDK, Version 2. The private key material of a key generated with EC2 is stored in a string. I am trying to generate the public key material that is necessary to import the key into EC2 using OpenSSL::PKey::RSA

After that I am trying to import the key pair.

It looks like this:

kk=OpenSSL::PKey::RSA.new my_private_key_material
pub=kk.public_key
ec2.import_key_pair({key_name: "my_key", public_key_material: pub.export})

The API is throwing this error:

*** Aws::EC2::Errors::InvalidKeyFormat Exception: Key is not in valid OpenSSH public key format

I am not sure what is wrong and how to generate the public key material correctly. I already tried to Base64 encode the public key string without success.

Edit

I tried a couple of new things. I generated a new key using the EC2 web console from scratch and then geneerated the public one the way Raphael points out below with

openssl rsa -in mykey.pem -outform PEM -pubout -out mykey.pub

The key is not encrypted.

Whey trying to import the public key, either with the web console or by code, I get the same error.

Edit 2

I found this.

When generating the public key with a different command, it works:

ssh-keygen -y

The generated public key looks different. It starts with

ssh-rsa AAAAB3NzaC1yc2EAAAADA....

While the first generated one starts with

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG....

Now the question is how to generate the first format in ruby. I also found this post on different formats.

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
Michael
  • 137
  • 2
  • 10
  • 1
    Is your key encrypted? – Raphael May 05 '17 at 18:23
  • No. Not according to [this post](https://security.stackexchange.com/questions/129724/how-to-check-if-an-ssh-private-key-has-passphrase-or-not). It also has no passphrase and was generated using the standard EC2 procedure. – Michael May 05 '17 at 18:42
  • 1
    Are you able to generate the pub key from the private using other tool, like: `openssl rsa -in mykey.pem -pubout > mykey.pub`. Try to do this to check the validity of private key generated. Maybe some parameters are missing or wrong. – Raphael May 05 '17 at 18:48
  • OK. I just tried it and generated the key like this. It was generated, but when importing it, I got the same message. This time I imported it directly using the EC2 management console. I repeated the whole procedure with a freshly generated key. Same issue. – Michael May 05 '17 at 19:46
  • Sorry, was the key pem encoded? I forgot the paramenter in the comand, it should be `openssl rsa -in mykey.pem -outform PEM -pubout -out mykey.pub` – Raphael May 05 '17 at 20:20
  • How did you generate the key? Did u use 'create_key_pair' API or ssh keygen or openssl ? – agent420 May 06 '17 at 02:09
  • @Raphael, thx again. I tried it but without success. – Michael May 06 '17 at 04:25
  • @agent420, create_key_pair or directly using the ec2 web console UI – Michael May 06 '17 at 04:26
  • When you use EC2 console or AWS SDKs to generate a key, it's public key is already stored by AWS EC2. You do not need to import it. – agent420 May 06 '17 at 04:45

4 Answers4

1

OK, I solved it by following this post.

It turned out the public key had to be generated in a different way

kk=OpenSSL::PKey::RSA.new my_private_key_material
key=kk.public_key

type = key.ssh_type
data = [ key.to_blob ].pack('m0')

openssh_format = "#{type} #{data}"

ec2.import_key_pair({key_name: "my_key", public_key_material: openssh_format})
Community
  • 1
  • 1
Michael
  • 137
  • 2
  • 10
  • It's interesting and odd, the pack(m0) encodes the string to Base64, how did you try to encode it before? was it using Base64.encode64? – Raphael May 06 '17 at 16:16
1

The documentation suggests that key contents must be encoded in Base64 client-side, however this is not the case: The SSH key contents should be provided as-is, in the format "ssh-rsa XXXXX....".

Ivy
  • 3,393
  • 11
  • 33
  • 46
0

Rory is right. In NodeJS below code worked.

let keypair = fs.readFileSync(homedir + '/.ssh/id_rsa.pub');
result = await ec2.importKeyPair({
    KeyName: 'KeyPairName',
    PublicKeyMaterial: keypair,
}).promise();
Sanjay Vamja
  • 2,235
  • 1
  • 16
  • 16
0

I m using Ruby SDK V3 and this is work for me to import key to AWS

#!/usr/bin/env ruby
require 'rubygems'
require 'aws-sdk-ec2'


key_content = File.read('/home/xxx/keys/sshkey.pub')
ec2_client =  Aws::EC2::Client.new()
resp = ec2_client.import_key_pair({
  dry_run: false,
  key_name: "test-ruby-key",
  public_key_material: key_content,
})

Hope it helpful!

Yvette Lau
  • 191
  • 1
  • 7