1

I'm trying to generate an RSA public-private key pair. The public key will be uploaded to AWS CloudFront. I found a code sample here and changed two things:

  • bitsize is 2048. According to CloudFront documentation, this is the expected bit size.
  • Type for public key is PUBLIC KEY. CloudFront expects -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- lines.

Here's the final code:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "io/ioutil"
)

func main() {
    filename := "key"
    bitSize := 2048

    // Generate RSA key.
    key, err := rsa.GenerateKey(rand.Reader, bitSize)
    if err != nil {
        panic(err)
    }

    // Extract public component.
    pub := key.Public()

    // Encode private key to PKCS#1 ASN.1 PEM.
    keyPEM := pem.EncodeToMemory(
        &pem.Block{
            Type:  "RSA PRIVATE KEY",
            Bytes: x509.MarshalPKCS1PrivateKey(key),
        },
    )

    // Encode public key to PKCS#1 ASN.1 PEM.
    pubPEM := pem.EncodeToMemory(
        &pem.Block{
            Type:  "PUBLIC KEY",
            Bytes: x509.MarshalPKCS1PublicKey(pub.(*rsa.PublicKey)),
        },
    )

    // Write private key to file.
    if err := ioutil.WriteFile(filename+".rsa", keyPEM, 0700); err != nil {
        panic(err)
    }

    // Write public key to file.
    if err := ioutil.WriteFile(filename+".rsa.pub", pubPEM, 0755); err != nil {
        panic(err)
    }
}

When I upload the public key to CloudFront, I get the following error:

Your request contains empty/invalid/out of limits RSA Encoded Key

This code needs to run in a Lambda and rotate a secret in SecretsManager. Locally, I can run openssl genrsa and openssl rsa commands. The public key will then be accepted by CloudFront.

Why is the public key generated by the code not being accepted and how can the code be fixed?

user246392
  • 2,661
  • 11
  • 54
  • 96

1 Answers1

0

If you are using Ruby SDK v3, you can generate cloudfront RSA key pair and upload the key by doing this

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

key = OpenSSL::PKey::RSA.new 2048

open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
cloudfront_public_content = File.read('public_key.pem')


cloudfront_client = Aws::CloudFront::Client.new()
cloudfront_public_key_resp = cloudfront_client.create_public_key({
  public_key_config: { 
    caller_reference: "test-key-ruby", 
    name: "test-ruby-key", 
    encoded_key: cloudfront_public_content,
    comment: "string",
  },
})
p cloudfront_public_key_resp.public_key.id

save the above codes as file test.rb and just run

ruby test.rb
Yvette Lau
  • 191
  • 1
  • 7