go解析含passphrase的pem秘钥

背景

在编写TLS配置时需要用到需要用到一串包含passphrase的RSA秘钥,本想通过官方库的方式解析使用,但由于安全因素,官方已经禁用了DecryptPEMBlockEncryptPEMBlockIsEncryptedPEMBlock等函数,导致无法通过官方库去实现这个需求。

解决方案

最终通过pkcs8库来完成需求,代码如下:

go 复制代码
package main

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"

	"github.com/youmark/pkcs8"
)

func main() {
	pem, err := getTlsConfig()
	if err != nil {
		panic(err)
	}
	fmt.Println("无加密的pem:", string(pem))
}

func getTlsConfig() ([]byte, error) {
	passphrase := "test123"
	keyFilePaaht := "./key"

	keyPEMByte, err := os.ReadFile(keyFilePaaht)
	if err != nil {
		err = fmt.Errorf("read %s failed! err: %s", keyFilePaaht, err)
		return nil, err
	}

	keyPEMBlock, rest := pem.Decode(keyPEMByte)
	if len(rest) > 0 {
		err := fmt.Errorf("decode key failed! rest: %s", rest)
		return nil, err
	}

	// 解析pem
	key, err := pkcs8.ParsePKCS8PrivateKey(keyPEMBlock.Bytes, []byte(passphrase))
	if err != nil {
		err = fmt.Errorf("parse PKCS8 private key err: %s", err)
		return nil, err
	}

	// 解析出其中的RSA 私钥
	keyBytes, err := x509.MarshalPKCS8PrivateKey(key)
	if err != nil {
		err = fmt.Errorf("MarshalPKCS8PrivateKey failed! %s", err)
		return nil, err
	}
	// 编码成新的PEM 结构
	newKey := pem.EncodeToMemory(
		&pem.Block{
			Type:  "PRIVATE KEY",
			Bytes: keyBytes,
		},
	)

	return newKey, nil
}

为什么GO不支持pem的加密?

GO团队的Commit Message

crypto/x509: deprecate legacy PEM encryption

It's unfortunate that we don't implement PKCS#8 encryption (#8860)

so we can't recommend an alternative but PEM encryption is so broken

that it's worth deprecating outright.

官方库x509

Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since it does not authenticate the ciphertext, it is vulnerable to padding oracle attacks that can let an attacker recover the plaintext.

GO团队认为PEM encryption的实现是不好的,不够安全的,因此官方移除了实现,并且也不推荐相关的外部实现的库。

从这个Issue的讨论可以看出社区对这个需求的渴望已经很久,但官方并没有太多关注。

参考链接

相关推荐
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于SpringBoot的校园快递APP系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
喵个咪1 小时前
GoWind Content Hub|风行,开箱即用的企业级前后端一体内容中台
前端·后端·cms
小码哥_常2 小时前
警惕!别让@Async成为服务器的“资源杀手”
后端
qq_256247052 小时前
解剖大型语言模型:剥开人工智能的“黑盒”
后端
代码探秘者2 小时前
【算法篇】3.位运算
java·数据结构·后端·python·算法·spring
Anastasiozzzz2 小时前
告别 Class:深入理解 Go 语言的面向对象编程
开发语言·后端·golang
ai安歌2 小时前
学生管理系统——Django实现登录验证码功能:从生成到验证的完整方案
后端·python·django
文心快码BaiduComate3 小时前
Comate Spec Mode能力升级:让复杂任务开发更可控、更稳定
前端·后端
MX_93593 小时前
Spring整合Web环境实现思路
java·开发语言·后端·spring
星浩AI3 小时前
MCP 系列(协议篇):深入理解 MCP 协议机制
后端·langchain·agent