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