如何为 CloudFront 生成 RSA 公私密钥对

分享于2023年02月01日 amazon-cloudfront amazon-web-services aws-lambda aws-secrets-manager go 问答
【问题标题】:How to generate an RSA public-private key pair for CloudFront如何为 CloudFront 生成 RSA 公私密钥对
【发布时间】:2023-01-14 03:37:20
【问题描述】:

我正在尝试生成一个 RSA 公私密钥对。公钥将上传到 AWS CloudFront。我找到了一个代码示例 here 并更改了两件事:

  • 位大小为 2048 。根据 CloudFront 文档,这是预期的位大小。
  • 公钥的类型是 PUBLIC KEY 。 CloudFront 需要 -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY----- 行。

这是最终代码:

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

当我将公钥上传到 CloudFront 时,出现以下错误:

您的请求包含空/无效/超出限制的 RSA 编码密钥

此代码需要在 Lambda 中运行并在 SecretsManager 中轮换密钥。在本地,我可以运行 openssl genrsa openssl rsa 命令。 CloudFront 随后将接受公钥。

为什么代码生成的公钥不被接受,如何修复代码?


【解决方案1】:

如果您使用的是 Ruby SDK v3,则可以生成云端 RSA 密钥对并通过执行此操作上传密钥

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

将以上代码保存为文件 test.rb 就跑

ruby test.rb

【讨论】: