github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/x509/sec1.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package x509 6 7 /* 8 x509/sec1.go 椭圆曲线公私钥与其SEC 1, ASN.1 DER字节数组之间的相互转换 9 目前支持sm2, ecdsa 10 11 ParseECPrivateKey : 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 12 MarshalECPrivateKey : 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 13 */ 14 15 import ( 16 "crypto/ecdsa" 17 "crypto/elliptic" 18 "encoding/asn1" 19 "errors" 20 "fmt" 21 "math/big" 22 23 "github.com/hxx258456/ccgo/sm2" 24 ) 25 26 const ecPrivKeyVersion = 1 27 28 // 椭圆曲线私钥结构体 29 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 30 // References: 31 // 32 // RFC 5915 33 // SEC1 - http://www.secg.org/sec1-v2.pdf 34 // 35 // Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 36 // most cases it is not. 37 type ecPrivateKey struct { 38 Version int 39 PrivateKey []byte 40 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 41 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 42 } 43 44 // ParseECPrivateKey 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 45 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey 46 // 47 // ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form. 48 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 49 func ParseECPrivateKey(der []byte) (interface{}, error) { 50 return parseECPrivateKey(nil, der) 51 } 52 53 // MarshalECPrivateKey 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 54 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey 55 // 56 // MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form. 57 // 58 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 59 // For a more flexible key format which is not EC specific, use 60 // MarshalPKCS8PrivateKey. 61 func MarshalECPrivateKey(key interface{}) ([]byte, error) { 62 switch priv := key.(type) { 63 case *ecdsa.PrivateKey: 64 oid, ok := oidFromNamedCurve(priv.Curve) 65 if !ok { 66 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 67 } 68 if oid.Equal(oidNamedCurveP256SM2) { 69 return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves") 70 } 71 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 72 return asn1.Marshal(ecPrivateKey{ 73 Version: ecPrivKeyVersion, 74 PrivateKey: priv.D.FillBytes(privateKey), 75 NamedCurveOID: oid, 76 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 77 }) 78 case *sm2.PrivateKey: 79 oid, ok := oidFromNamedCurve(priv.Curve) 80 if !ok { 81 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 82 } 83 if !oid.Equal(oidNamedCurveP256SM2) { 84 return nil, errors.New("gmx509.MarshalECPrivateKey: not sm2 curve") 85 } 86 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 87 return asn1.Marshal(ecPrivateKey{ 88 Version: ecPrivKeyVersion, 89 PrivateKey: priv.D.FillBytes(privateKey), 90 NamedCurveOID: oid, 91 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 92 }) 93 // var ecPriv ecPrivateKey 94 // ecPriv.Version = ecPrivKeyVersion 95 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 96 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 97 // ecPriv.PrivateKey = priv.D.Bytes() 98 // return asn1.Marshal(ecPriv) 99 } 100 return nil, errors.New("x509: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 101 } 102 103 // parseECPrivateKey根据namedCurveOID获取对应的椭圆曲线,并将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 104 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey 105 // 106 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 107 // The OID for the named curve may be provided from another source (such as 108 // the PKCS8 container) - if it is provided then use this instead of the OID 109 // that may exist in the EC private key structure. 110 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key interface{}, err error) { 111 var privKey ecPrivateKey 112 // 尝试将 der 反序列化到 privKey 113 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 114 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil { 115 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") 116 } 117 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 118 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)") 119 } 120 return nil, fmt.Errorf("gmx509.parseECPrivateKey: failed to parse EC private key: %s", err.Error()) 121 } 122 // 检查版本 123 if privKey.Version != ecPrivKeyVersion { 124 return nil, fmt.Errorf("gmx509.parseECPrivateKey: unknown EC private key version %d", privKey.Version) 125 } 126 var curve elliptic.Curve 127 // namedCurveOID有可能为nil,因为ecdsa在其序列化(pkcs8.go的MarshalPKCS8PrivateKey)分支里并没有传入oid到序列化结构中去。 128 if namedCurveOID != nil { 129 // 根据namedCurveOID获取曲线 130 curve = namedCurveFromOID(*namedCurveOID) 131 } else { 132 // namedCurveOID为空则使用私钥的NamedCurveOID 133 curve = namedCurveFromOID(privKey.NamedCurveOID) 134 } 135 if curve == nil { 136 return nil, errors.New("gmx509.parseECPrivateKey: unknown elliptic curve") 137 } 138 // 检查私钥数值是否小于曲线参数N 139 k := new(big.Int).SetBytes(privKey.PrivateKey) 140 curveOrder := curve.Params().N 141 if k.Cmp(curveOrder) >= 0 { 142 return nil, errors.New("gmx509.parseECPrivateKey: invalid elliptic curve private key value") 143 } 144 // 根据曲线选择生成对应完整私钥 145 switch curve { 146 case sm2.P256Sm2(): 147 priv := new(sm2.PrivateKey) 148 priv.Curve = curve 149 priv.D = k 150 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 151 // Some private keys have leading zero padding. This is invalid 152 // according to [SEC1], but this code will ignore it. 153 for len(privKey.PrivateKey) > len(privateKey) { 154 if privKey.PrivateKey[0] != 0 { 155 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 156 } 157 privKey.PrivateKey = privKey.PrivateKey[1:] 158 } 159 // Some private keys remove all leading zeros, this is also invalid 160 // according to [SEC1] but since OpenSSL used to do this, we ignore 161 // this too. 162 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 163 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 164 return priv, nil 165 case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521(): 166 priv := new(ecdsa.PrivateKey) 167 priv.Curve = curve 168 priv.D = k 169 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 170 // Some private keys have leading zero padding. This is invalid 171 // according to [SEC1], but this code will ignore it. 172 for len(privKey.PrivateKey) > len(privateKey) { 173 if privKey.PrivateKey[0] != 0 { 174 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 175 } 176 privKey.PrivateKey = privKey.PrivateKey[1:] 177 } 178 // Some private keys remove all leading zeros, this is also invalid 179 // according to [SEC1] but since OpenSSL used to do this, we ignore 180 // this too. 181 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 182 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 183 return priv, nil 184 } 185 return nil, errors.New("gmx509.parseECPrivateKey: failed to parseECPrivateKey: Unknown curve") 186 } 187 188 // marshalECPrivateKeyWithOID根据oid将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 189 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey 190 // 191 // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and 192 // sets the curve ID to the given OID, or omits it if OID is nil. 193 func marshalECPrivateKeyWithOID(key interface{}, oid asn1.ObjectIdentifier) ([]byte, error) { 194 switch priv := key.(type) { 195 case *ecdsa.PrivateKey: 196 if oid.Equal(oidNamedCurveP256SM2) { 197 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves") 198 } 199 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 200 return asn1.Marshal(ecPrivateKey{ 201 Version: ecPrivKeyVersion, 202 PrivateKey: priv.D.FillBytes(privateKey), 203 NamedCurveOID: oid, 204 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 205 }) 206 case *sm2.PrivateKey: 207 if !oid.Equal(oidNamedCurveP256SM2) { 208 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not sm2 curve") 209 } 210 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 211 return asn1.Marshal(ecPrivateKey{ 212 Version: ecPrivKeyVersion, 213 PrivateKey: priv.D.FillBytes(privateKey), 214 NamedCurveOID: oid, 215 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 216 }) 217 // var ecPriv ecPrivateKey 218 // ecPriv.Version = ecPrivKeyVersion 219 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 220 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 221 // ecPriv.PrivateKey = priv.D.Bytes() 222 // return asn1.Marshal(ecPriv) 223 } 224 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 225 }