gitee.com/lh-her-team/common@v1.5.1/crypto/asym/asym_fast.go (about) 1 //go:build linux 2 // +build linux 3 4 package asym 5 6 import "C" 7 import ( 8 crypto2 "crypto" 9 ecdsa2 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rand" 12 rsa2 "crypto/rsa" 13 "crypto/sha256" 14 "crypto/x509" 15 "encoding/asn1" 16 "encoding/hex" 17 "encoding/pem" 18 "fmt" 19 "io" 20 "io/ioutil" 21 "math/big" 22 "path/filepath" 23 "strings" 24 25 "gitee.com/lh-her-team/common/crypto/engine" 26 27 "github.com/pkg/errors" 28 29 "gitee.com/lh-her-team/common/opencrypto" 30 gmsm2 "gitee.com/lh-her-team/common/opencrypto/gmssl/sm2" 31 32 "github.com/btcsuite/btcd/btcec" 33 tjsm2 "github.com/tjfoc/gmsm/sm2" 34 smx509 "github.com/tjfoc/gmsm/x509" 35 36 "gitee.com/lh-her-team/common/crypto" 37 "gitee.com/lh-her-team/common/crypto/asym/ecdsa" 38 "gitee.com/lh-her-team/common/crypto/asym/rsa" 39 "gitee.com/lh-her-team/common/crypto/asym/sm2" 40 ) 41 42 const pemBegin = "-----BEGIN" 43 44 // 生成签名公私钥对 45 func GenerateKeyPair(keyType crypto.KeyType) (crypto.PrivateKey, error) { 46 switch keyType { 47 case crypto.SM2: 48 if !engine.IsTls { 49 switch engine.CryptoEngine { 50 case opencrypto.GmSSL: 51 return gmsm2.GenerateKeyPair() 52 } 53 } 54 return sm2.New(keyType) 55 case crypto.ECC_NISTP256, crypto.ECC_NISTP384, crypto.ECC_NISTP521, crypto.ECC_Secp256k1: 56 return ecdsa.New(keyType) 57 case crypto.RSA512, crypto.RSA1024, crypto.RSA2048, crypto.RSA3072: 58 return rsa.New(keyType) 59 case crypto.ECC_Ed25519: 60 return nil, fmt.Errorf("unsupport signature algorithm") 61 default: 62 return nil, fmt.Errorf("wrong signature algorithm type") 63 } 64 } 65 66 func GenerateKeyPairBytes(keyType crypto.KeyType) (sk, pk []byte, err error) { 67 var priv crypto.PrivateKey 68 if priv, err = GenerateKeyPair(keyType); err != nil { 69 return 70 } 71 if sk, err = priv.Bytes(); err != nil { 72 return 73 } 74 if pk, err = priv.PublicKey().Bytes(); err != nil { 75 return 76 } 77 return sk, pk, nil 78 } 79 80 func GenerateKeyPairPEM(keyType crypto.KeyType) (sk string, pk string, err error) { 81 var priv crypto.PrivateKey 82 if priv, err = GenerateKeyPair(keyType); err != nil { 83 return "", "", err 84 } 85 // Serialization for bitcoin signature key: encode ECC numbers with hex 86 if sk, err = priv.String(); err != nil { 87 return "", "", err 88 } 89 // Serialization for bitcoin signature key: encode ECC numbers with hex 90 if pk, err = priv.PublicKey().String(); err != nil { 91 return "", "", err 92 } 93 return sk, pk, nil 94 } 95 96 // Generate public-private key pair for encryption 97 func GenerateEncKeyPair(keyType crypto.KeyType) (crypto.DecryptKey, error) { 98 switch keyType { 99 case crypto.SM2: 100 key, err := ecdsa.New(keyType) 101 if err != nil { 102 return nil, err 103 } 104 return key.(crypto.DecryptKey), nil 105 case crypto.RSA512, crypto.RSA1024, crypto.RSA2048, crypto.RSA3072: 106 return rsa.NewDecryptionKey(keyType) 107 default: 108 return nil, fmt.Errorf("unsupported encryption algorithm type") 109 } 110 } 111 112 // ParsePrivateKey parse bytes to a private key. 113 func ParsePrivateKey(der []byte) (crypto2.PrivateKey, error) { 114 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 115 return key, nil 116 } 117 if key, err := x509.ParseECPrivateKey(der); err == nil { 118 return key, nil 119 } 120 if key, err := smx509.ParsePKCS8UnecryptedPrivateKey(der); err == nil { 121 return key, nil 122 } 123 // Serialization for bitcoin signature key: encode ECC numbers with hex 124 Secp256k1Key, _ := btcec.PrivKeyFromBytes(btcec.S256(), der) 125 key := Secp256k1Key.ToECDSA() 126 return key, nil 127 } 128 129 func ParsePublicKey(der []byte) (crypto2.PublicKey, error) { 130 if key, err := x509.ParsePKCS1PublicKey(der); err == nil { 131 return key, nil 132 } 133 if key, err := x509.ParsePKIXPublicKey(der); err == nil { 134 return key, nil 135 } 136 if key, err := smx509.ParseSm2PublicKey(der); err == nil { 137 return key, nil 138 } 139 // Serialization for bitcoin signature key: encode ECC numbers with hex 140 if key, err := btcec.ParsePubKey(der, btcec.S256()); err == nil { 141 return key.ToECDSA(), nil 142 } 143 return nil, errors.New("failed to parse public key") 144 } 145 146 func PrivateKeyFromDER(der []byte) (crypto.PrivateKey, error) { 147 if !engine.IsTls { 148 switch engine.CryptoEngine { 149 case opencrypto.GmSSL: 150 if pri, err := gmsm2.UnmarshalPrivateKey(der); err == nil { 151 return pri, nil 152 } 153 } 154 } 155 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 156 return &rsa.PrivateKey{K: key}, nil 157 } 158 if key, err := x509.ParseECPrivateKey(der); err == nil { 159 if key.Curve == tjsm2.P256Sm2() { 160 k := &tjsm2.PrivateKey{ 161 PublicKey: tjsm2.PublicKey{ 162 Curve: tjsm2.P256Sm2(), 163 X: key.X, 164 Y: key.Y, 165 }, 166 D: key.D, 167 } 168 return &sm2.PrivateKey{K: k}, nil 169 } else { 170 return &ecdsa.PrivateKey{K: key}, nil 171 } 172 } 173 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { 174 switch k := key.(type) { 175 case *ecdsa2.PrivateKey: 176 return &ecdsa.PrivateKey{K: k}, nil 177 case *tjsm2.PrivateKey: 178 return &sm2.PrivateKey{K: k}, nil 179 case *rsa2.PrivateKey: 180 return &rsa.PrivateKey{K: k}, nil 181 case crypto.PrivateKey: 182 return k, nil 183 default: 184 return nil, fmt.Errorf("fail to parse private key, unrecognized key type [%T]", key) 185 } 186 } 187 if key, err := smx509.ParsePKCS8UnecryptedPrivateKey(der); err == nil { 188 return &sm2.PrivateKey{K: key}, nil 189 } 190 Secp256k1Key, _ := btcec.PrivKeyFromBytes(btcec.S256(), der) 191 key := Secp256k1Key.ToECDSA() 192 return &ecdsa.PrivateKey{K: key}, nil 193 } 194 195 func PublicKeyFromDER(der []byte) (crypto.PublicKey, error) { 196 if !engine.IsTls { 197 switch engine.CryptoEngine { 198 case opencrypto.GmSSL: 199 if pub, err := gmsm2.UnmarshalPublicKey(der); err == nil { 200 return pub, nil 201 } 202 } 203 } 204 if key, err := x509.ParsePKCS1PublicKey(der); err == nil { 205 return &rsa.PublicKey{K: key}, nil 206 } 207 if key, err := x509.ParsePKIXPublicKey(der); err == nil { 208 switch key := key.(type) { 209 case *rsa2.PublicKey: 210 return &rsa.PublicKey{K: key}, nil 211 case *ecdsa2.PublicKey: 212 return &ecdsa.PublicKey{K: key}, nil 213 case *tjsm2.PublicKey: 214 return &sm2.PublicKey{K: key}, nil 215 case crypto.PublicKey: 216 return key, nil 217 default: 218 return nil, fmt.Errorf("unsupported public key type [%T]", key) 219 } 220 } 221 if key, err := smx509.ParseSm2PublicKey(der); err == nil { 222 return &sm2.PublicKey{K: key}, nil 223 } 224 if key, err := btcec.ParsePubKey(der, btcec.S256()); err == nil { 225 return &ecdsa.PublicKey{K: key.ToECDSA()}, nil 226 } 227 return nil, errors.New("failed to parse public key") 228 } 229 230 func PrivateKeyFromPEM(raw []byte, pwd []byte) (crypto.PrivateKey, error) { 231 var err error 232 if len(raw) <= 0 { 233 return nil, errors.New("PEM is nil") 234 } 235 if !strings.Contains(string(raw), pemBegin) { 236 var keyBytes []byte 237 keyBytes, err = hex.DecodeString(string(raw)) 238 if err != nil { 239 return nil, fmt.Errorf("fail to decode public key: [%v]", err) 240 } 241 return PrivateKeyFromDER(keyBytes) 242 } 243 block, _ := pem.Decode(raw) 244 if block == nil { 245 return PrivateKeyFromDER(raw) 246 } 247 plain := block.Bytes 248 // TODO: 249 // nolint: staticcheck 250 if x509.IsEncryptedPEMBlock(block) { 251 if len(pwd) <= 0 { 252 return nil, errors.New("missing password for encrypted PEM") 253 } 254 // nolint: staticcheck 255 plain, err = x509.DecryptPEMBlock(block, pwd) 256 if err != nil { 257 return nil, fmt.Errorf("fail to decrypt PEM: [%s]", err) 258 } 259 } 260 return PrivateKeyFromDER(plain) 261 } 262 263 func PublicKeyFromPEM(raw []byte) (crypto.PublicKey, error) { 264 if len(raw) <= 0 { 265 return nil, errors.New("PEM is nil") 266 } 267 if !strings.Contains(string(raw), pemBegin) { 268 keyBytes, err := hex.DecodeString(string(raw)) 269 if err != nil { 270 return nil, fmt.Errorf("fail to decode public key: [%v]", err) 271 } 272 return PublicKeyFromDER(keyBytes) 273 } 274 block, _ := pem.Decode(raw) 275 if block == nil { 276 return PublicKeyFromDER(raw) 277 } 278 return PublicKeyFromDER(block.Bytes) 279 } 280 281 func Sign(sk interface{}, data []byte) ([]byte, error) { 282 var ( 283 err error 284 r, s *big.Int 285 keyBytes []byte 286 signedData []byte 287 ) 288 keyBytes, err = loadKeyBytes(sk) 289 if err != nil { 290 return nil, err 291 } 292 //try to parse private key if crypto engine is set 293 if !engine.IsTls { 294 switch engine.CryptoEngine { 295 case opencrypto.GmSSL: 296 if pri, e := gmsm2.UnmarshalPrivateKey(keyBytes); e == nil { 297 return pri.Sign(data) 298 } 299 } 300 } 301 key, err := ParsePrivateKey(keyBytes) 302 if err != nil { 303 return nil, err 304 } 305 switch key := key.(type) { 306 case *ecdsa2.PrivateKey: 307 if r, s, err = ecdsa2.Sign(rand.Reader, key, data); err != nil { 308 return nil, err 309 } 310 return asn1.Marshal(ecdsa.Sig{R: r, S: s}) 311 case *tjsm2.PrivateKey: 312 if r, s, err = sm2SignWithoutHash(key, data); err != nil { 313 return nil, err 314 } 315 return asn1.Marshal(ecdsa.Sig{R: r, S: s}) 316 case *rsa2.PrivateKey: 317 hashed := sha256.Sum256(data) 318 if signedData, err = rsa2.SignPKCS1v15(rand.Reader, key, crypto2.SHA256, hashed[:]); err != nil { 319 return nil, err 320 } 321 return signedData, nil 322 default: 323 return nil, fmt.Errorf("fail to sign: unsupported algorithm") 324 } 325 } 326 327 func Verify(pk interface{}, data, sig []byte) (bool, error) { 328 if sig == nil { 329 return false, fmt.Errorf("nil signature") 330 } 331 var ( 332 err error 333 keyBytes []byte 334 ) 335 keyBytes, err = loadKeyBytes(pk) 336 if err != nil { 337 return false, err 338 } 339 //try to parse public key if crypto engine is set 340 if !engine.IsTls { 341 switch engine.CryptoEngine { 342 case opencrypto.GmSSL: 343 if pri, e := gmsm2.UnmarshalPublicKey(keyBytes); e == nil { 344 return pri.Verify(data, sig) 345 } 346 } 347 } 348 key, err := ParsePublicKey(keyBytes) 349 if err != nil { 350 return false, err 351 } 352 if err := verifyDataSignWithPubKey(key, data, sig); err != nil { 353 return false, err 354 } 355 return true, nil 356 } 357 358 var one = new(big.Int).SetInt64(1) 359 360 func randFieldElement(c elliptic.Curve, random io.Reader) (k *big.Int, err error) { 361 if random == nil { 362 random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it. 363 } 364 params := c.Params() 365 b := make([]byte, params.BitSize/8+8) 366 _, err = io.ReadFull(random, b) 367 if err != nil { 368 return 369 } 370 k = new(big.Int).SetBytes(b) 371 n := new(big.Int).Sub(params.N, one) 372 k.Mod(k, n) 373 k.Add(k, one) 374 return 375 } 376 377 func sm2SignWithoutHash(priv *tjsm2.PrivateKey, digest []byte) (r, s *big.Int, err error) { 378 e := new(big.Int).SetBytes(digest) 379 c := priv.PublicKey.Curve 380 N := c.Params().N 381 if N.Sign() == 0 { 382 return nil, nil, errors.New("zero parameter") 383 } 384 var k *big.Int 385 for { // 调整算法细节以实现SM2 386 for { 387 k, err = randFieldElement(c, rand.Reader) 388 if err != nil { 389 r = nil 390 return 391 } 392 r, _ = priv.Curve.ScalarBaseMult(k.Bytes()) 393 r.Add(r, e) 394 r.Mod(r, N) 395 if r.Sign() != 0 { 396 if t := new(big.Int).Add(r, k); t.Cmp(N) != 0 { 397 break 398 } 399 } 400 } 401 rD := new(big.Int).Mul(priv.D, r) 402 s = new(big.Int).Sub(k, rD) 403 d1 := new(big.Int).Add(priv.D, one) 404 d1Inv := new(big.Int).ModInverse(d1, N) 405 s.Mul(s, d1Inv) 406 s.Mod(s, N) 407 if s.Sign() != 0 { 408 break 409 } 410 } 411 return 412 } 413 414 func loadKeyBytes(key interface{}) ([]byte, error) { 415 var keyBytes []byte 416 switch k := key.(type) { 417 case string: 418 if strings.Contains(k, pemBegin) { 419 der, _ := pem.Decode([]byte(k)) 420 keyBytes = der.Bytes 421 } else { 422 var err error 423 keyBytes, err = hex.DecodeString(k) 424 if err != nil { 425 return nil, err 426 } 427 } 428 case []byte: 429 keyBytes = k 430 default: 431 return nil, errors.New("invalid key format") 432 } 433 return keyBytes, nil 434 } 435 436 func verifyDataSignWithPubKey(key crypto2.PublicKey, data, sig []byte) error { 437 switch key := key.(type) { 438 case *ecdsa2.PublicKey: 439 sigStruct := &ecdsa.Sig{} 440 if _, err := asn1.Unmarshal(sig, sigStruct); err != nil { 441 return err 442 } 443 if !ecdsa2.Verify(key, data, sigStruct.R, sigStruct.S) { 444 return fmt.Errorf("string invalid ecdsa signature") 445 } 446 case *tjsm2.PublicKey: 447 sigStruct := &ecdsa.Sig{} 448 if _, err := asn1.Unmarshal(sig, sigStruct); err != nil { 449 return err 450 } 451 if !tjsm2.Verify(key, data, sigStruct.R, sigStruct.S) { 452 return fmt.Errorf("invalid sm2 signature") 453 } 454 case *rsa2.PublicKey: 455 hashed := sha256.Sum256(data) 456 err := rsa2.VerifyPKCS1v15(key, crypto2.SHA256, hashed[:], sig) 457 if err != nil { 458 return err 459 } 460 default: 461 return fmt.Errorf("fail to verify: unsupported algorithm") 462 } 463 return nil 464 } 465 466 func WriteFile(keyType crypto.KeyType, filePath string) error { 467 sk, pk, err := GenerateKeyPairPEM(keyType) 468 if err != nil { 469 return err 470 } 471 skPath := filepath.Join(filePath, "node.key") 472 if err = ioutil.WriteFile(skPath, []byte(sk), 0644); err != nil { 473 return fmt.Errorf("save sk failed, %s", err) 474 } 475 pkPath := filepath.Join(filePath, "node.crt") 476 if err = ioutil.WriteFile(pkPath, []byte(pk), 0644); err != nil { 477 return fmt.Errorf("save pk failed, %s", err) 478 } 479 return nil 480 } 481 482 func ParseSM2PublicKey(asn1Data []byte) (*tjsm2.PublicKey, error) { 483 if asn1Data == nil { 484 return nil, errors.New("fail to unmarshal public key: public key is empty") 485 } 486 x, y := elliptic.Unmarshal(tjsm2.P256Sm2(), asn1Data) 487 if x == nil { 488 return nil, errors.New("x509: failed to unmarshal elliptic curve point") 489 } 490 pk := tjsm2.PublicKey{ 491 Curve: tjsm2.P256Sm2(), 492 X: x, 493 Y: y, 494 } 495 return &pk, nil 496 }