gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/x509/pkcs8.go (about) 1 // Copyright 2011 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/pkcs8.go PKCS#8标准DER字节数组与对应私钥之间的相互转换。 9 私钥支持: sm2, ecdsa, ed25519, rsa 10 11 ParsePKCS8PrivateKey : 将未加密的PKCS #8, ASN.1 DER格式字节数组转为对应的私钥 12 MarshalPKCS8PrivateKey : 将私钥转为PKCS #8, ASN.1 DER字节数组 13 14 PKCS#8 是私钥消息表示标准(Private-Key Information Syntax Standard). 15 reference to RFC5959 and RFC2898 16 */ 17 18 import ( 19 "crypto/ecdsa" 20 "crypto/ed25519" 21 "crypto/rsa" 22 "crypto/x509/pkix" 23 "encoding/asn1" 24 "errors" 25 "fmt" 26 "gitee.com/ks-custle/core-gm/ecdsa_ext" 27 28 "gitee.com/ks-custle/core-gm/sm2" 29 ) 30 31 // pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See 32 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 33 // and RFC 5208. 34 type pkcs8 struct { 35 Version int 36 Algo pkix.AlgorithmIdentifier 37 PrivateKey []byte 38 // optional attributes omitted. 39 } 40 41 const ( 42 ErrMsgUseParseECPrivateKey = "gmx509.ParsePKCS8PrivateKey: failed to parse private key (use ParseECPrivateKey instead for this key format)" 43 ErrMsgUseParsePKCS1PrivateKey = "gmx509.ParsePKCS8PrivateKey: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)" 44 ) 45 46 // ParsePKCS8PrivateKey 将未加密的PKCS #8, ASN.1 DER格式字节数组转为对应的私钥。 47 // - 私钥支持: sm2, ecdsa, ecdsa_ext, ed25519, rsa 48 // 49 // ParsePKCS8PrivateKey parses an unencrypted private key in PKCS #8, ASN.1 DER form. 50 // 51 // It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, or a ed25519.PrivateKey. 52 // More types might be supported in the future. 53 // 54 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY". 55 func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { 56 var privKey pkcs8 57 // 尝试将 der 反序列化到 privKey 58 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 59 if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil { 60 return nil, errors.New(ErrMsgUseParseECPrivateKey) 61 } 62 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 63 return nil, errors.New(ErrMsgUseParsePKCS1PrivateKey) 64 } 65 return nil, err 66 } 67 // 根据反序列化后的公钥算法标识生成对应的私钥 68 switch { 69 case privKey.Algo.Algorithm.Equal(oidPublicKeySM2): 70 bytes := privKey.Algo.Parameters.FullBytes 71 namedCurveOID := new(asn1.ObjectIdentifier) 72 // 尝试获取曲线oid 73 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 74 namedCurveOID = nil 75 } 76 // 根据曲线oid获取对应曲线并生成对应私钥 77 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 78 if err != nil { 79 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: failed to parse EC private key embedded in PKCS#8: %s", err.Error()) 80 } 81 return key, nil 82 case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): 83 key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) 84 if err != nil { 85 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: failed to parse RSA private key embedded in PKCS#8: %s", err.Error()) 86 } 87 return key, nil 88 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): 89 bytes := privKey.Algo.Parameters.FullBytes 90 namedCurveOID := new(asn1.ObjectIdentifier) 91 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 92 namedCurveOID = nil 93 } 94 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 95 if err != nil { 96 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: failed to parse EC private key embedded in PKCS#8: %s", err.Error()) 97 } 98 return key, nil 99 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSAEXT): 100 bytes := privKey.Algo.Parameters.FullBytes 101 namedCurveOID := new(asn1.ObjectIdentifier) 102 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 103 namedCurveOID = nil 104 } 105 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 106 if err != nil { 107 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: failed to parse EC private key embedded in PKCS#8: %s", err.Error()) 108 } 109 return key, nil 110 case privKey.Algo.Algorithm.Equal(oidPublicKeyEd25519): 111 if l := len(privKey.Algo.Parameters.FullBytes); l != 0 { 112 return nil, errors.New("gmx509.ParsePKCS8PrivateKey: invalid Ed25519 private key parameters") 113 } 114 var curvePrivateKey []byte 115 if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil { 116 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: invalid Ed25519 private key: %v", err) 117 } 118 if l := len(curvePrivateKey); l != ed25519.SeedSize { 119 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: invalid Ed25519 private key length: %d", l) 120 } 121 return ed25519.NewKeyFromSeed(curvePrivateKey), nil 122 default: 123 return nil, fmt.Errorf("gmx509.ParsePKCS8PrivateKey: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) 124 } 125 } 126 127 // MarshalPKCS8PrivateKey 将私钥转为PKCS #8, ASN.1 DER字节数组 128 // - 私钥支持: sm2, ecdsa, ecdsa_ext, ed25519, rsa 129 // 130 // MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form. 131 // 132 // The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey 133 // and ed25519.PrivateKey. Unsupported key types result in an error. 134 // 135 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY". 136 func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) { 137 var privKey pkcs8 138 139 switch k := key.(type) { 140 case *sm2.PrivateKey: 141 oid, ok := oidFromNamedCurve(k.Curve) 142 if !ok { 143 return nil, fmt.Errorf("gmx509.MarshalPKCS8PrivateKey: unknown curve: [%s]", k.Curve.Params().Name) 144 } 145 oidBytes, err := asn1.Marshal(oid) 146 if err != nil { 147 return nil, fmt.Errorf("gmx509.MarshalPKCS8PrivateKey: failed to marshal curve OID: [%s]", err.Error()) 148 } 149 privKey.Algo = pkix.AlgorithmIdentifier{ 150 Algorithm: oidPublicKeySM2, 151 Parameters: asn1.RawValue{ 152 FullBytes: oidBytes, 153 }, 154 } 155 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, oid); err != nil { 156 return nil, fmt.Errorf("gmx509.MarshalPKCS8PrivateKey: failed to marshal EC private key while building PKCS#8: " + err.Error()) 157 } 158 case *rsa.PrivateKey: 159 privKey.Algo = pkix.AlgorithmIdentifier{ 160 Algorithm: oidPublicKeyRSA, 161 Parameters: asn1.NullRawValue, 162 } 163 privKey.PrivateKey = MarshalPKCS1PrivateKey(k) 164 case *ecdsa.PrivateKey: 165 oid, ok := oidFromNamedCurve(k.Curve) 166 if !ok { 167 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: unknown curve while marshaling to PKCS#8") 168 } 169 oidBytes, err := asn1.Marshal(oid) 170 if err != nil { 171 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: failed to marshal curve OID: " + err.Error()) 172 } 173 privKey.Algo = pkix.AlgorithmIdentifier{ 174 Algorithm: oidPublicKeyECDSA, 175 Parameters: asn1.RawValue{ 176 FullBytes: oidBytes, 177 }, 178 } 179 // 注意, ecdsa并没有将曲线oid传入序列化结构中 180 // 大约是为了与openssl的结果对应 181 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { 182 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: failed to marshal EC private key while building PKCS#8: " + err.Error()) 183 } 184 case *ecdsa_ext.PrivateKey: 185 oid, ok := oidFromNamedCurve(k.Curve) 186 if !ok { 187 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: unknown curve while marshaling to PKCS#8") 188 } 189 oidBytes, err := asn1.Marshal(oid) 190 if err != nil { 191 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: failed to marshal curve OID: " + err.Error()) 192 } 193 privKey.Algo = pkix.AlgorithmIdentifier{ 194 Algorithm: oidPublicKeyECDSAEXT, 195 Parameters: asn1.RawValue{ 196 FullBytes: oidBytes, 197 }, 198 } 199 // 注意, ecdsa并没有将曲线oid传入序列化结构中 200 // 大约是为了与openssl的结果对应 201 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { 202 return nil, errors.New("gmx509.MarshalPKCS8PrivateKey: failed to marshal EC private key while building PKCS#8: " + err.Error()) 203 } 204 case ed25519.PrivateKey: 205 privKey.Algo = pkix.AlgorithmIdentifier{ 206 Algorithm: oidPublicKeyEd25519, 207 } 208 curvePrivateKey, err := asn1.Marshal(k.Seed()) 209 if err != nil { 210 return nil, fmt.Errorf("gmx509.MarshalPKCS8PrivateKey: failed to marshal private key: %v", err) 211 } 212 privKey.PrivateKey = curvePrivateKey 213 default: 214 return nil, fmt.Errorf("gmx509.MarshalPKCS8PrivateKey: unknown key type while marshaling PKCS#8: %T", key) 215 } 216 return asn1.Marshal(privKey) 217 }