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  }