You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

代码生成的RSA公钥无法上传CloudFront,如何修复?

问题描述

尝试生成RSA公私钥对,公钥用于上传至AWS CloudFront。参考示例代码后做了两处修改:

  • 密钥位数设为2048,符合CloudFront文档要求;
  • 公钥PEM类型设为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时收到错误:

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

本地通过openssl genrsa和openssl rsa命令生成的公钥可正常被CloudFront接受,该代码需在Lambda中运行并轮换SecretsManager中的密钥,请问代码生成的公钥不被接受的原因是什么,该如何修复?


原因分析

问题出在公钥编码格式与PEM头的不匹配:

  • 代码中用x509.MarshalPKCS1PublicKey生成的是PKCS#1格式的公钥内容,但给PEM块指定的Type是PUBLIC KEY——这是矛盾的。
  • PUBLIC KEY类型的PEM头,对应的必须是PKIX(X.509 SubjectPublicKeyInfo)格式的公钥;而PKCS#1格式的公钥,对应的PEM Type应该是RSA PUBLIC KEY。
  • CloudFront要求的-----BEGIN PUBLIC KEY-----格式,只接受PKIX编码的公钥,不兼容PKCS#1编码。

本地openssl生成的公钥能正常工作,是因为openssl rsa -pubout默认生成的就是PKIX格式的公钥,正好匹配CloudFront的要求。


修复方案

将公钥的编码方式从x509.MarshalPKCS1PublicKey替换为x509.MarshalPKIXPublicKey,同时保留PEM块的Type为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 PKIX (X.509) format instead of PKCS#1
    pubASN1, err := x509.MarshalPKIXPublicKey(pub.(*rsa.PublicKey))
    if err != nil {
        panic(err)
    }
    pubPEM := pem.EncodeToMemory(
        &pem.Block{
            Type:  "PUBLIC KEY",
            Bytes: pubASN1,
        },
    )

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

验证方式

生成公钥后,可通过以下openssl命令验证格式是否正确:

openssl rsa -in key.rsa.pub -pubin -text -noout

如果能正常输出公钥的模数、指数等信息,说明格式符合要求,可正常上传至CloudFront。

内容的提问来源于stack exchange,提问作者user246392

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:45:30