emmansun / gmsm

ShangMi (SM) cipher suites for golang (Go语言商用密码软件)

Home Page:https://emmansun.github.io/gmsm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

openssl 1.1.1 生成的pem私钥解析失败,是我方法不对吗?

kakuilan opened this issue · comments

commented

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
}
commented

可以了,谢谢