openssl 1.1.1 生成的pem私钥解析失败,是我方法不对吗?
kakuilan opened this issue · comments
go版本为go version go1.20.4 linux/amd64
gmsm版本为 v0.20.2
openssl生成如下
$ openssl version
OpenSSL 1.1.1v 1 Aug 2023
#生成私钥
openssl ecparam -genkey -name SM2 -out sm2_private_key.pem
#私钥转pkcs8
openssl pkcs8 -topk8 -inform PEM -in sm2_private_key.pem -outform pem -nocrypt -out sm2_private_key_pkcs8.pem
#生成公钥
openssl ec -in sm2_private_key.pem -pubout -out sm2_public_key.pem
它们的值分别为:
sm2_private_key.pem
-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFvtv7CG1ieW6s0OA1YfLENgf+iNTyxiHCLV4BsQHHQOoAoGCCqBHM9V
AYItoUQDQgAEP0sfXc8azCcIKB5kO+l+oOBKDP9nGgptBODsr6wFWGIqaqCNiYRX
HKvWWAuXAPXDI/SVtJeXwbUh6d3UnesDRw==
-----END EC PRIVATE KEY-----
sm2_private_key_pkcs8.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgW+2/sIbWJ5bqzQ4D
Vh8sQ2B/6I1PLGIcItXgGxAcdA6hRANCAAQ/Sx9dzxrMJwgoHmQ76X6g4EoM/2ca
Cm0E4OyvrAVYYipqoI2JhFccq9ZYC5cA9cMj9JW0l5fBtSHp3dSd6wNH
-----END PRIVATE KEY-----
sm2_public_key.pem
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEP0sfXc8azCcIKB5kO+l+oOBKDP9n
GgptBODsr6wFWGIqaqCNiYRXHKvWWAuXAPXDI/SVtJeXwbUh6d3UnesDRw==
-----END PUBLIC KEY-----
公钥解析代码为
func ParsePublicKeySM2(data []byte) (*ecdsa.PublicKey, error) {
block, _ := pem.Decode(data)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, errors.New("Failed to decode public key")
}
pub, err := smx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
publicKey := pub.(*ecdsa.PublicKey)
return publicKey, nil
}
公钥可以成功解析。
私钥解析代码为
func ParsePKCS8PrivateKeySM2(data []byte) (*sm2.PrivateKey, error) {
return pkcs8.ParsePKCS8PrivateKeySM2(data)
}
不过私钥无论是用sm2_private_key.pem,还是sm2_private_key_pkcs8.pem,都解析失败,都提示如下
asn1: structure error: tags don't match (16 vs {class:0 tag:13 length:45 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} pkcs8 @2
是我使用方法不对吗?
你可以参考pkcs8的sample 代码:
func ExampleParsePrivateKey_withoutPassword() {
const privateKeyPem = `
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl
K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2
85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh
-----END PRIVATE KEY-----`
block, _ := pem.Decode([]byte(privateKeyPem))
if block == nil {
fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n")
return
}
pk, params, err := pkcs8.ParsePrivateKey(block.Bytes, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Error from ParsePrivateKey: %s\n", err)
return
}
if params == nil && pk != nil {
fmt.Println("ok")
} else {
fmt.Println("fail")
}
// Output: ok
}
可以了,谢谢