Go语言解析OpenSSL生成的RSASSA-PSS私钥出现未知算法错误
报错原因
返回错误中的OID 1.2.840.113549.1.1.10 对应RSASSA-PSS签名算法,低于1.15版本的Go标准库x509.ParsePKCS8PrivateKey原生不支持解析带RSASSA-PSS专属标识的PKCS8私钥,高版本Go如果遇到严格封装PSS参数的密钥也可能触发兼容问题。
解决方案
可根据实际场景选择以下任意一种方案解决:
方案1:升级Go版本到1.15及以上
Go 1.15版本开始官方正式支持RSASSA-PSS密钥解析,升级后原有代码无需修改即可正常运行,同时建议将已弃用的ioutil.ReadFile替换为os.ReadFile避免编译警告。
方案2:生成/转换为兼容格式的密钥
如果暂时无法升级Go版本,可通过OpenSSL命令调整密钥格式,使用传统RSA标识替代PSS专属标识:
# 新生成兼容格式的2048位RSA密钥 openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.key # 转换已有的RSASSA-PSS格式密钥为兼容格式 openssl pkcs8 -topk8 -inform PEM -in 原有PSS密钥路径 -outform PEM -out private_key.compat.key -traditional
方案3:手动解析PSS私钥(适配低版本Go)
必须使用低于1.15版本Go的场景下,可配合x/crypto库手动解析PSS私钥,示例代码如下:
import ( "crypto/x509" "encoding/pem" "log" "os" "golang.org/x/crypto/cryptobyte" "golang.org/x/crypto/cryptobyte/asn1" ) func parsePKCS8PSSKey(der []byte) (interface{}, error) { var seq cryptobyte.String input := cryptobyte.String(der) if !input.ReadASN1(&seq, asn1.SEQUENCE) || !seq.Skip(2) || // 跳过版本号字段 !seq.ReadASN1(&seq, asn1.SEQUENCE) || // 跳过PSS算法标识段 !input.ReadASN1(&seq, asn1.OCTET_STRING) { return nil, x509.IncorrectPasswordError{} } return x509.ParsePKCS1PrivateKey(seq) } func main() { privateKeyPath := "private_key.key" data, err := os.ReadFile(privateKeyPath) if err != nil { log.Fatal(err) } block, _ := pem.Decode(data) key, err := x509.ParsePKCS8PrivateKey(block.Bytes) // 命中PSS解析错误时走自定义解析逻辑 if err != nil && err.Error() == "x509: PKCS#8 wrapping contained private key with unknown algorithm: 1.2.840.113549.1.1.10" { key, err = parsePKCS8PSSKey(block.Bytes) } if err != nil { log.Fatal(err) } // 后续使用key逻辑 }
内容的提问来源于stack exchange,提问作者Nikita Kiose
相关产品推荐
相关产品推荐

