gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/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 "gitee.com/zhaochuninhefei/gmgo/ecdsa_ext" 22 "math/big" 23 24 "gitee.com/zhaochuninhefei/gmgo/sm2" 25 ) 26 27 const ecPrivKeyVersion = 1 28 29 // ecPrivateKey 椭圆曲线私钥结构体, 添加用于识别私钥类型的字段(目前支持sm2/ecdsa/ecdsa_ext) 30 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 31 // References: 32 // RFC 5915 33 // SEC1 - http://www.secg.org/sec1-v2.pdf 34 // Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 35 // most cases it is not. 36 type ecPrivateKey struct { 37 Version int 38 PrivateKey []byte 39 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 40 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 41 42 // 用于识别私钥类型的字段 43 PrivType string `asn1:"optional,explicit,tag:2"` 44 } 45 46 // ParseECPrivateKey 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 47 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 48 // 49 // ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form. 50 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 51 func ParseECPrivateKey(der []byte) (interface{}, error) { 52 return parseECPrivateKey(nil, der) 53 } 54 55 // MarshalECPrivateKey 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 56 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 57 // 58 // MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form. 59 // 60 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 61 // For a more flexible key format which is not EC specific, use 62 // MarshalPKCS8PrivateKey. 63 func MarshalECPrivateKey(key interface{}) ([]byte, error) { 64 switch priv := key.(type) { 65 case *ecdsa.PrivateKey: 66 oid, ok := oidFromNamedCurve(priv.Curve) 67 if !ok { 68 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 69 } 70 if oid.Equal(oidNamedCurveP256SM2) { 71 return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves") 72 } 73 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 74 return asn1.Marshal(ecPrivateKey{ 75 Version: ecPrivKeyVersion, 76 PrivateKey: priv.D.FillBytes(privateKey), 77 NamedCurveOID: oid, 78 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 79 PrivType: "ecdsa", 80 }) 81 case *ecdsa_ext.PrivateKey: 82 oid, ok := oidFromNamedCurve(priv.Curve) 83 if !ok { 84 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 85 } 86 if oid.Equal(oidNamedCurveP256SM2) { 87 return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves") 88 } 89 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 90 return asn1.Marshal(ecPrivateKey{ 91 Version: ecPrivKeyVersion, 92 PrivateKey: priv.D.FillBytes(privateKey), 93 NamedCurveOID: oid, 94 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 95 PrivType: "ecdsa_ext", 96 }) 97 case *sm2.PrivateKey: 98 oid, ok := oidFromNamedCurve(priv.Curve) 99 if !ok { 100 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 101 } 102 if !oid.Equal(oidNamedCurveP256SM2) { 103 return nil, errors.New("gmx509.MarshalECPrivateKey: not sm2 curve") 104 } 105 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 106 return asn1.Marshal(ecPrivateKey{ 107 Version: ecPrivKeyVersion, 108 PrivateKey: priv.D.FillBytes(privateKey), 109 NamedCurveOID: oid, 110 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 111 PrivType: "sm2", 112 }) 113 // var ecPriv ecPrivateKey 114 // ecPriv.Version = ecPrivKeyVersion 115 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 116 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 117 // ecPriv.PrivateKey = priv.D.Bytes() 118 // return asn1.Marshal(ecPriv) 119 } 120 return nil, errors.New("x509: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 121 } 122 123 // parseECPrivateKey根据namedCurveOID获取对应的椭圆曲线,并将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 124 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 125 // 126 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 127 // The OID for the named curve may be provided from another source (such as 128 // the PKCS8 container) - if it is provided then use this instead of the OID 129 // that may exist in the EC private key structure. 130 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key interface{}, err error) { 131 var privKey ecPrivateKey 132 // 尝试将 der 反序列化到 privKey 133 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 134 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil { 135 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") 136 } 137 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 138 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)") 139 } 140 return nil, fmt.Errorf("gmx509.parseECPrivateKey: failed to parse EC private key: %s", err.Error()) 141 } 142 // 检查版本 143 if privKey.Version != ecPrivKeyVersion { 144 return nil, fmt.Errorf("gmx509.parseECPrivateKey: unknown EC private key version %d", privKey.Version) 145 } 146 var curve elliptic.Curve 147 // namedCurveOID有可能为nil,因为ecdsa在其序列化(pkcs8.go的MarshalPKCS8PrivateKey)分支里并没有传入oid到序列化结构中去。 148 if namedCurveOID != nil { 149 // 根据namedCurveOID获取曲线 150 curve = namedCurveFromOID(*namedCurveOID) 151 } else { 152 // namedCurveOID为空则使用私钥的NamedCurveOID 153 curve = namedCurveFromOID(privKey.NamedCurveOID) 154 } 155 if curve == nil { 156 return nil, errors.New("gmx509.parseECPrivateKey: unknown elliptic curve") 157 } 158 // 检查私钥数值是否小于曲线参数N 159 k := new(big.Int).SetBytes(privKey.PrivateKey) 160 curveOrder := curve.Params().N 161 if k.Cmp(curveOrder) >= 0 { 162 return nil, errors.New("gmx509.parseECPrivateKey: invalid elliptic curve private key value") 163 } 164 // 根据曲线选择生成对应完整私钥 165 switch curve { 166 case sm2.P256Sm2(): 167 priv := new(sm2.PrivateKey) 168 priv.Curve = curve 169 priv.D = k 170 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 171 // Some private keys have leading zero padding. This is invalid 172 // according to [SEC1], but this code will ignore it. 173 for len(privKey.PrivateKey) > len(privateKey) { 174 if privKey.PrivateKey[0] != 0 { 175 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 176 } 177 privKey.PrivateKey = privKey.PrivateKey[1:] 178 } 179 // Some private keys remove all leading zeros, this is also invalid 180 // according to [SEC1] but since OpenSSL used to do this, we ignore 181 // this too. 182 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 183 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 184 return priv, nil 185 case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521(): 186 switch privKey.PrivType { 187 case "ecdsa", "": 188 priv := new(ecdsa.PrivateKey) 189 priv.Curve = curve 190 priv.D = k 191 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 192 // Some private keys have leading zero padding. This is invalid 193 // according to [SEC1], but this code will ignore it. 194 for len(privKey.PrivateKey) > len(privateKey) { 195 if privKey.PrivateKey[0] != 0 { 196 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 197 } 198 privKey.PrivateKey = privKey.PrivateKey[1:] 199 } 200 // Some private keys remove all leading zeros, this is also invalid 201 // according to [SEC1] but since OpenSSL used to do this, we ignore 202 // this too. 203 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 204 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 205 return priv, nil 206 case "ecdsa_ext": 207 priv := new(ecdsa_ext.PrivateKey) 208 priv.Curve = curve 209 priv.D = k 210 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 211 // Some private keys have leading zero padding. This is invalid 212 // according to [SEC1], but this code will ignore it. 213 for len(privKey.PrivateKey) > len(privateKey) { 214 if privKey.PrivateKey[0] != 0 { 215 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 216 } 217 privKey.PrivateKey = privKey.PrivateKey[1:] 218 } 219 // Some private keys remove all leading zeros, this is also invalid 220 // according to [SEC1] but since OpenSSL used to do this, we ignore 221 // this too. 222 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 223 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 224 return priv, nil 225 } 226 } 227 return nil, errors.New("gmx509.parseECPrivateKey: failed to parseECPrivateKey: Unknown curve") 228 } 229 230 // marshalECPrivateKeyWithOID根据oid将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 231 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 232 // 233 // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and 234 // sets the curve ID to the given OID, or omits it if OID is nil. 235 func marshalECPrivateKeyWithOID(key interface{}, oid asn1.ObjectIdentifier) ([]byte, error) { 236 switch priv := key.(type) { 237 case *ecdsa.PrivateKey: 238 if oid.Equal(oidNamedCurveP256SM2) { 239 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves") 240 } 241 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 242 return asn1.Marshal(ecPrivateKey{ 243 Version: ecPrivKeyVersion, 244 PrivateKey: priv.D.FillBytes(privateKey), 245 NamedCurveOID: oid, 246 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 247 PrivType: "ecdsa", 248 }) 249 case *ecdsa_ext.PrivateKey: 250 if oid.Equal(oidNamedCurveP256SM2) { 251 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves") 252 } 253 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 254 return asn1.Marshal(ecPrivateKey{ 255 Version: ecPrivKeyVersion, 256 PrivateKey: priv.D.FillBytes(privateKey), 257 NamedCurveOID: oid, 258 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 259 PrivType: "ecdsa_ext", 260 }) 261 case *sm2.PrivateKey: 262 if !oid.Equal(oidNamedCurveP256SM2) { 263 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not sm2 curve") 264 } 265 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 266 return asn1.Marshal(ecPrivateKey{ 267 Version: ecPrivKeyVersion, 268 PrivateKey: priv.D.FillBytes(privateKey), 269 NamedCurveOID: oid, 270 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 271 PrivType: "sm2", 272 }) 273 // var ecPriv ecPrivateKey 274 // ecPriv.Version = ecPrivKeyVersion 275 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 276 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 277 // ecPriv.PrivateKey = priv.D.Bytes() 278 // return asn1.Marshal(ecPriv) 279 } 280 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 281 }