github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/x509/pkcs8.go (about) 1 /* 2 Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package x509 17 18 import ( 19 "crypto/aes" 20 "crypto/cipher" 21 "crypto/elliptic" 22 "crypto/hmac" 23 "crypto/md5" 24 "crypto/rand" 25 "crypto/sha1" 26 "crypto/sha256" 27 "crypto/sha512" 28 "crypto/x509/pkix" 29 "encoding/asn1" 30 "errors" 31 "hash" 32 "math/big" 33 "reflect" 34 35 "github.com/Hyperledger-TWGC/tjfoc-gm/sm2" 36 ) 37 38 /* 39 * reference to RFC5959 and RFC2898 40 */ 41 42 var ( 43 oidPBES1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 3} // pbeWithMD5AndDES-CBC(PBES1) 44 oidPBES2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13} // id-PBES2(PBES2) 45 oidPBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12} // id-PBKDF2 46 47 oidKEYMD5 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 5} 48 oidKEYSHA1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 7} 49 oidKEYSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9} 50 oidKEYSHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 11} 51 52 oidAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2} 53 oidAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42} 54 55 oidSM2 = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} 56 ) 57 58 // reference to https://www.rfc-editor.org/rfc/rfc5958.txt 59 type PrivateKeyInfo struct { 60 Version int // v1 or v2 61 PrivateKeyAlgorithm []asn1.ObjectIdentifier 62 PrivateKey []byte 63 } 64 65 // reference to https://www.rfc-editor.org/rfc/rfc5958.txt 66 type EncryptedPrivateKeyInfo struct { 67 EncryptionAlgorithm Pbes2Algorithms 68 EncryptedData []byte 69 } 70 71 // reference to https://www.ietf.org/rfc/rfc2898.txt 72 type Pbes2Algorithms struct { 73 IdPBES2 asn1.ObjectIdentifier 74 Pbes2Params Pbes2Params 75 } 76 77 // reference to https://www.ietf.org/rfc/rfc2898.txt 78 type Pbes2Params struct { 79 KeyDerivationFunc Pbes2KDfs // PBES2-KDFs 80 EncryptionScheme Pbes2Encs // PBES2-Encs 81 } 82 83 // reference to https://www.ietf.org/rfc/rfc2898.txt 84 type Pbes2KDfs struct { 85 IdPBKDF2 asn1.ObjectIdentifier 86 Pkdf2Params Pkdf2Params 87 } 88 89 type Pbes2Encs struct { 90 EncryAlgo asn1.ObjectIdentifier 91 IV []byte 92 } 93 94 // reference to https://www.ietf.org/rfc/rfc2898.txt 95 type Pkdf2Params struct { 96 Salt []byte 97 IterationCount int 98 Prf pkix.AlgorithmIdentifier 99 } 100 101 type sm2PrivateKey struct { 102 Version int 103 PrivateKey []byte 104 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 105 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 106 } 107 108 type pkcs8 struct { 109 Version int 110 Algo pkix.AlgorithmIdentifier 111 PrivateKey []byte 112 } 113 114 // copy from crypto/pbkdf2.go 115 func pbkdf(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { 116 prf := hmac.New(h, password) 117 hashLen := prf.Size() 118 numBlocks := (keyLen + hashLen - 1) / hashLen 119 120 var buf [4]byte 121 dk := make([]byte, 0, numBlocks*hashLen) 122 U := make([]byte, hashLen) 123 for block := 1; block <= numBlocks; block++ { 124 // N.B.: || means concatenation, ^ means XOR 125 // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter 126 // U_1 = PRF(password, salt || uint(i)) 127 prf.Reset() 128 prf.Write(salt) 129 buf[0] = byte(block >> 24) 130 buf[1] = byte(block >> 16) 131 buf[2] = byte(block >> 8) 132 buf[3] = byte(block) 133 prf.Write(buf[:4]) 134 dk = prf.Sum(dk) 135 T := dk[len(dk)-hashLen:] 136 copy(U, T) 137 138 // U_n = PRF(password, U_(n-1)) 139 for n := 2; n <= iter; n++ { 140 prf.Reset() 141 prf.Write(U) 142 U = U[:0] 143 U = prf.Sum(U) 144 for x := range U { 145 T[x] ^= U[x] 146 } 147 } 148 } 149 return dk[:keyLen] 150 } 151 152 func ParseSm2PublicKey(der []byte) (*sm2.PublicKey, error) { 153 var pubkey pkixPublicKey 154 155 if _, err := asn1.Unmarshal(der, &pubkey); err != nil { 156 return nil, err 157 } 158 if !reflect.DeepEqual(pubkey.Algo.Algorithm, oidSM2) { 159 return nil, errors.New("x509: not sm2 elliptic curve") 160 } 161 curve := sm2.P256Sm2() 162 x, y := elliptic.Unmarshal(curve, pubkey.BitString.Bytes) 163 pub := sm2.PublicKey{ 164 Curve: curve, 165 X: x, 166 Y: y, 167 } 168 return &pub, nil 169 } 170 171 func MarshalSm2PublicKey(key *sm2.PublicKey) ([]byte, error) { 172 var r pkixPublicKey 173 var algo pkix.AlgorithmIdentifier 174 175 if(key.Curve.Params()!=sm2.P256Sm2().Params()){ 176 return nil, errors.New("x509: unsupported elliptic curve") 177 } 178 algo.Algorithm = oidSM2 179 algo.Parameters.Class = 0 180 algo.Parameters.Tag = 6 181 algo.Parameters.IsCompound = false 182 algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301}) 183 r.Algo = algo 184 r.BitString = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)} 185 return asn1.Marshal(r) 186 } 187 188 func ParseSm2PrivateKey(der []byte) (*sm2.PrivateKey, error) { 189 var privKey sm2PrivateKey 190 191 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 192 return nil, errors.New("x509: failed to parse SM2 private key: " + err.Error()) 193 } 194 curve := sm2.P256Sm2() 195 k := new(big.Int).SetBytes(privKey.PrivateKey) 196 curveOrder := curve.Params().N 197 if k.Cmp(curveOrder) >= 0 { 198 return nil, errors.New("x509: invalid elliptic curve private key value") 199 } 200 priv := new(sm2.PrivateKey) 201 priv.Curve = curve 202 priv.D = k 203 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 204 for len(privKey.PrivateKey) > len(privateKey) { 205 if privKey.PrivateKey[0] != 0 { 206 return nil, errors.New("x509: invalid private key length") 207 } 208 privKey.PrivateKey = privKey.PrivateKey[1:] 209 } 210 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 211 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 212 return priv, nil 213 } 214 215 func ParsePKCS8UnecryptedPrivateKey(der []byte) (*sm2.PrivateKey, error) { 216 var privKey pkcs8 217 218 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 219 return nil, err 220 } 221 if !reflect.DeepEqual(privKey.Algo.Algorithm, oidSM2) { 222 return nil, errors.New("x509: not sm2 elliptic curve") 223 } 224 return ParseSm2PrivateKey(privKey.PrivateKey) 225 } 226 227 func ParsePKCS8EcryptedPrivateKey(der, pwd []byte) (*sm2.PrivateKey, error) { 228 var keyInfo EncryptedPrivateKeyInfo 229 230 _, err := asn1.Unmarshal(der, &keyInfo) 231 if err != nil { 232 return nil, errors.New("x509: unknown format") 233 } 234 if !reflect.DeepEqual(keyInfo.EncryptionAlgorithm.IdPBES2, oidPBES2) { 235 return nil, errors.New("x509: only support PBES2") 236 } 237 encryptionScheme := keyInfo.EncryptionAlgorithm.Pbes2Params.EncryptionScheme 238 keyDerivationFunc := keyInfo.EncryptionAlgorithm.Pbes2Params.KeyDerivationFunc 239 if !reflect.DeepEqual(keyDerivationFunc.IdPBKDF2, oidPBKDF2) { 240 return nil, errors.New("x509: only support PBKDF2") 241 } 242 pkdf2Params := keyDerivationFunc.Pkdf2Params 243 if !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES128CBC) && 244 !reflect.DeepEqual(encryptionScheme.EncryAlgo, oidAES256CBC) { 245 return nil, errors.New("x509: unknow encryption algorithm") 246 } 247 iv := encryptionScheme.IV 248 salt := pkdf2Params.Salt 249 iter := pkdf2Params.IterationCount 250 encryptedKey := keyInfo.EncryptedData 251 var key []byte 252 switch { 253 case pkdf2Params.Prf.Algorithm.Equal(oidKEYMD5): 254 key = pbkdf(pwd, salt, iter, 32, md5.New) 255 break 256 case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA1): 257 key = pbkdf(pwd, salt, iter, 32, sha1.New) 258 break 259 case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA256): 260 key = pbkdf(pwd, salt, iter, 32, sha256.New) 261 break 262 case pkdf2Params.Prf.Algorithm.Equal(oidKEYSHA512): 263 key = pbkdf(pwd, salt, iter, 32, sha512.New) 264 break 265 default: 266 return nil, errors.New("x509: unknown hash algorithm") 267 } 268 block, err := aes.NewCipher(key) 269 if err != nil { 270 return nil, err 271 } 272 mode := cipher.NewCBCDecrypter(block, iv) 273 mode.CryptBlocks(encryptedKey, encryptedKey) 274 rKey, err := ParsePKCS8UnecryptedPrivateKey(encryptedKey) 275 if err != nil { 276 return nil, errors.New("pkcs8: incorrect password") 277 } 278 return rKey, nil 279 } 280 281 func ParsePKCS8PrivateKey(der, pwd []byte) (*sm2.PrivateKey, error) { 282 if pwd == nil { 283 284 return ParsePKCS8UnecryptedPrivateKey(der) 285 } 286 return ParsePKCS8EcryptedPrivateKey(der, pwd) 287 } 288 289 func MarshalSm2UnecryptedPrivateKey(key *sm2.PrivateKey) ([]byte, error) { 290 var r pkcs8 291 var priv sm2PrivateKey 292 var algo pkix.AlgorithmIdentifier 293 294 algo.Algorithm = oidSM2 295 algo.Parameters.Class = 0 296 algo.Parameters.Tag = 6 297 algo.Parameters.IsCompound = false 298 algo.Parameters.FullBytes = []byte{6, 8, 42, 129, 28, 207, 85, 1, 130, 45} // asn1.Marshal(asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301}) 299 priv.Version = 1 300 priv.NamedCurveOID = oidNamedCurveP256SM2 301 priv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)} 302 priv.PrivateKey = key.D.Bytes() 303 r.Version = 0 304 r.Algo = algo 305 r.PrivateKey, _ = asn1.Marshal(priv) 306 return asn1.Marshal(r) 307 } 308 309 func MarshalSm2EcryptedPrivateKey(PrivKey *sm2.PrivateKey, pwd []byte) ([]byte, error) { 310 der, err := MarshalSm2UnecryptedPrivateKey(PrivKey) 311 if err != nil { 312 return nil, err 313 } 314 iter := 2048 315 salt := make([]byte, 8) 316 iv := make([]byte, 16) 317 rand.Reader.Read(salt) 318 rand.Reader.Read(iv) 319 key := pbkdf(pwd, salt, iter, 32, sha1.New) // 默认是SHA1 320 padding := aes.BlockSize - len(der)%aes.BlockSize 321 if padding > 0 { 322 n := len(der) 323 der = append(der, make([]byte, padding)...) 324 for i := 0; i < padding; i++ { 325 der[n+i] = byte(padding) 326 } 327 } 328 encryptedKey := make([]byte, len(der)) 329 block, err := aes.NewCipher(key) 330 if err != nil { 331 return nil, err 332 } 333 mode := cipher.NewCBCEncrypter(block, iv) 334 mode.CryptBlocks(encryptedKey, der) 335 var algorithmIdentifier pkix.AlgorithmIdentifier 336 algorithmIdentifier.Algorithm = oidKEYSHA1 337 algorithmIdentifier.Parameters.Tag = 5 338 algorithmIdentifier.Parameters.IsCompound = false 339 algorithmIdentifier.Parameters.FullBytes = []byte{5, 0} 340 keyDerivationFunc := Pbes2KDfs{ 341 oidPBKDF2, 342 Pkdf2Params{ 343 salt, 344 iter, 345 algorithmIdentifier, 346 }, 347 } 348 encryptionScheme := Pbes2Encs{ 349 oidAES256CBC, 350 iv, 351 } 352 pbes2Algorithms := Pbes2Algorithms{ 353 oidPBES2, 354 Pbes2Params{ 355 keyDerivationFunc, 356 encryptionScheme, 357 }, 358 } 359 encryptedPkey := EncryptedPrivateKeyInfo{ 360 pbes2Algorithms, 361 encryptedKey, 362 } 363 return asn1.Marshal(encryptedPkey) 364 } 365 366 func MarshalSm2PrivateKey(key *sm2.PrivateKey, pwd []byte) ([]byte, error) { 367 if pwd == nil { 368 return MarshalSm2UnecryptedPrivateKey(key) 369 } 370 return MarshalSm2EcryptedPrivateKey(key, pwd) 371 } 372