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的讨论可以看出社区对这个需求的渴望已经很久,但官方并没有太多关注。

参考链接

相关推荐
00后程序员6 分钟前
如何解决浏览器HTTPS不安全连接警告及SSL证书问题
后端
00后程序员6 分钟前
苹果App上架审核延迟7工作日无反应:如何通过App Store Connect和邮件询问进度
后端
DS小龙哥8 分钟前
基于物联网设计的蜂箱智能监测系统设计
后端
QZQ5418813 分钟前
C++编译期计算
后端
饕餮争锋16 分钟前
Spring内置的Bean作用域介绍
java·后端·spring
CryptoRzz18 分钟前
美股 (US) 与 墨西哥 (Mexico) 股票数据接口集成指南
后端
张人大 Renda Zhang39 分钟前
Java 虚拟线程 Virtual Thread:让“每请求一线程”在高并发时代复活
java·jvm·后端·spring·架构·web·虚拟线程
一勺菠萝丶1 小时前
解决 SLF4J 警告问题 - 完整指南
java·spring boot·后端
零日失眠者1 小时前
【文件管理系列】001:文件批量重命名工具
后端·shell
申阳1 小时前
Day 19:02. 基于 SpringBoot4 开发后台管理系统-项目初始化
前端·后端·程序员