OpenSSL generated SM2 key throws error on parsing
truekarthik opened this issue · comments
Trying to parse an SM2 private key created using OpenSSL throws an error - x509: PKCS#8 wrapping contained private key with unknown algorithm: 1.2.156.10197.1.301
Versions:
OpenSSL - v3.1.3
emmansun/gmsm - v0.24.1
Steps to reproduce the error:
-
Generate SM2 Private key using OpenSSL:
openssl ecparam -name SM2 -genkey -noout -out private-key.pem
-
Use the returned key string in the below code:
package main
import (
"encoding/pem"
"fmt"
"github.com/emmansun/gmsm/pkcs8"
)
func main() {
privateKey := "-----BEGIN PRIVATE KEY-----\nMIGIAgEAMBQGCCqBHM9VAYItBggqgRzPVQGCLQRtMGsCAQEEIIfYbABfRJN5ZBkW\nteXxzV0hzNrWBhN0Fmn0cJRqy50XoUQDQgAEbyM/EfFVSXAdxeZ3ovXSAtG3GD1v\nav+xanZVivqzzKU35ILFbXef9YkxHQOpQRRifIj99nJS7SH+cFH5S0jKLw==\n-----END PRIVATE KEY-----\n"
keyData := []byte(privateKey)
block, _ := pem.Decode(keyData)
_, err := pkcs8.ParsePKCS8PrivateKeySM2(block.Bytes)
fmt.Println(err)
}
Error returned is x509: PKCS#8 wrapping contained private key with unknown algorithm: 1.2.156.10197.1.301
Digging deeper into the code using a debugger, the ObjectIdentifier of this key's algorithm is oidNamedCurveP256SM2
but in this block of the code in line 52 of smx509/pkcs8.go
,
Lines 52 to 54 in ceff9bf
there is a not operator provided in the if condition, resulting in return x509.ParsePKCS8PrivateKey(der)
being executed which throws the error.
Am I missing something here or is this a bug? Thanks in advance.
Are you sure this is the pkcs8 private key? Looks more like SEC1 ECC private key.
It seems that many people disapprove of this implementation of openssl. openssl/openssl#22529, let me make this library compatible with this implementation first.
Thanks for the quick fix. Does this mean that this library is not compatible with OpenSSL SM2 keys and other functions like Sign/Verify may also not work with OpenSSL generated SM2 keys?
Thanks for the quick fix. Does this mean that this library is not compatible with OpenSSL SM2 keys and other functions like Sign/Verify may also not work with OpenSSL generated SM2 keys?
There are standards for SM2 Sign/Verify, Encrypt/Decrypt and so on, for the SM2 private key pkcs8 , there are no related national standards yet, we just treat SM2 private key similar like other NIST elliptic curves: NIST P224 NIST P256 NIST P382 NIST P521.
// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
// and RFC 5208.
type pkcs8 struct {
Version int
Algo pkix.AlgorithmIdentifier
PrivateKey []byte
// optional attributes omitted.
}
// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
// 5280, section 4.1.1.2.
type AlgorithmIdentifier struct {
Algorithm asn1.ObjectIdentifier
Parameters asn1.RawValue `asn1:"optional"`
}
That means Algo.Algorithm
is
// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
//
// id-ecPublicKey OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
and Alg.Parameters
will be the real Curve OID. I think there are more discussions in
So, we also can't say it's a fix, but just an enhancement to support such kind of openssl 3+
sm2 p8 format private key.
In general , if openssl 3+
used 1.2.156.10197.1.301
to replace 1.2.2840.10045.2.1
in pkcs8 private key, PKIX public key, csr, certificate, then there will be interoperability issues with most of implementations, Sign/Verify functions may not be impacted, but the prerequisite is that you can parse them.
Per checking those openssl 3 disucssions, issues, pulls, it seems smx509: can parse openssl v3.1.3 p8 sm2 private key is NOT enough, if you need to parse sm2 PKIX public, csr, certificate generated by openssl 3+, you will still encounter issues.
Let’s see if openssl3 will stick to its own opinion or change it to backward compatibility.
Thanks a lot for the detailed explanation. You can close the issue if you'd like.
openssl 3.2.1 will fix it.
openssl 3.2.1 will fix it.