如何在Golang中生成与openssl命令输出一致的.der格式文件
Golang 生成与 openssl 输出一致的 RSA 公钥 DER 文件实现方案
你给出的 openssl rsa -in private.pem -outform DER -pubout -out public.der 命令,本质是从 PEM 格式的 RSA 私钥中导出 PKCS#1 编码的 DER 格式 RSA 公钥,Golang 具体实现如下:
实现步骤
- 读取本地 PEM 格式 RSA 私钥文件内容
- 解码 PEM 块,校验私钥格式合法性
- 解析得到 RSA 私钥结构体
- 将公钥序列化为和 openssl 输出格式完全匹配的 PKCS#1 DER 字节流
- 将 DER 字节流写入输出文件
完整代码示例
package main import ( "crypto/x509" "encoding/pem" "os" ) func main() { // 1. 读取私钥文件内容 privPemBytes, err := os.ReadFile("private.pem") if err != nil { panic("read private key failed: " + err.Error()) } // 2. 解码PEM块 block, _ := pem.Decode(privPemBytes) if block == nil { panic("invalid PEM format file") } var privKey *rsa.PrivateKey // 3. 解析私钥,分两种格式处理 if block.Type == "RSA PRIVATE KEY" { // PKCS#1格式私钥 privKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { panic("parse PKCS1 private key failed: " + err.Error()) } } else if block.Type == "PRIVATE KEY" { // PKCS#8格式私钥 privKeyAny, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { panic("parse PKCS8 private key failed: " + err.Error()) } var ok bool privKey, ok = privKeyAny.(*rsa.PrivateKey) if !ok { panic("private key is not RSA type") } } else { panic("not a valid RSA private key PEM block") } // 4. 序列化公钥为PKCS#1格式DER,与openssl rsa -pubout输出完全一致 derBytes := x509.MarshalPKCS1PublicKey(&privKey.PublicKey) // 注意:如果需要匹配openssl pkey -pubout命令输出的SPKI格式DER,替换为下面代码 // derBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey) // if err != nil { // panic("marshal public key failed: " + err.Error()) // } // 5. 写入DER文件 err = os.WriteFile("public.der", derBytes, 0644) if err != nil { panic("write DER file failed: " + err.Error()) } }
一致性校验方法
执行以下命令对比Golang生成文件和openssl原生输出的一致性:
- 用openssl生成标准公钥DER文件:
openssl rsa -in private.pem -outform DER -pubout -out openssl_public.der - 对比两个文件:
diff public.der openssl_public.der,无输出则代表内容完全一致。
内容的提问来源于stack exchange,提问作者psk
相关产品推荐
相关产品推荐

