gitee.com/lh-her-team/common@v1.5.1/opencrypto/gmssl/sm2/publickey.go (about)

     1  package sm2
     2  
     3  import (
     4  	"crypto"
     5  	"encoding/pem"
     6  	"fmt"
     7  
     8  	"github.com/tjfoc/gmsm/sm2"
     9  
    10  	"github.com/tjfoc/gmsm/sm3"
    11  
    12  	"gitee.com/lh-her-team/common/opencrypto/utils"
    13  
    14  	tjx509 "github.com/tjfoc/gmsm/x509"
    15  
    16  	"gitee.com/lh-her-team/common/crypto/hash"
    17  
    18  	"gitee.com/lh-her-team/common/opencrypto/gmssl/gmssl"
    19  
    20  	bccrypto "gitee.com/lh-her-team/common/crypto"
    21  )
    22  
    23  type PublicKey struct {
    24  	*gmssl.PublicKey
    25  	pkPem string
    26  }
    27  
    28  // PublicKey implements bccyrpto.PublicKey
    29  var _ bccrypto.PublicKey = (*PublicKey)(nil)
    30  
    31  func (pk *PublicKey) verifyWithSM3(msg, sig []byte, uid string) bool {
    32  	dgst, err := pk.CalSM2Digest(uid, msg)
    33  	if err != nil {
    34  		return false
    35  	}
    36  	if err := pk.PublicKey.Verify("sm2sign", dgst, sig, nil); err != nil {
    37  		return false
    38  	}
    39  	return true
    40  }
    41  
    42  func (pk *PublicKey) CalSM2Digest(uid string, msg []byte) ([]byte, error) {
    43  	pkSM2, err := tjx509.ReadPublicKeyFromPem([]byte(pk.pkPem))
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	if len(uid) == 0 {
    48  		uid = bccrypto.CRYPTO_DEFAULT_UID
    49  	}
    50  	za, err := sm2.ZA(pkSM2, []byte(uid))
    51  	if err != nil {
    52  		return nil, fmt.Errorf("fail to create SM3 digest for msg [%v]", err)
    53  	}
    54  	e := sm3.New()
    55  	e.Write(za)
    56  	e.Write(msg)
    57  	dgst := e.Sum(nil)
    58  	return dgst, nil
    59  }
    60  
    61  func (pk *PublicKey) Bytes() ([]byte, error) {
    62  	p, _ := pem.Decode([]byte(pk.pkPem))
    63  	return p.Bytes, nil
    64  }
    65  
    66  func (pk *PublicKey) Type() bccrypto.KeyType {
    67  	return bccrypto.SM2
    68  }
    69  
    70  func (pk *PublicKey) String() (string, error) {
    71  	return pk.pkPem, nil
    72  }
    73  
    74  func (pk *PublicKey) Verify(msg []byte, sig []byte) (bool, error) {
    75  	return pk.verifyWithSM3(msg, sig, utils.SM2_DEFAULT_USER_ID), nil
    76  }
    77  
    78  func (pk *PublicKey) VerifyWithOpts(msg []byte, sig []byte, opts *bccrypto.SignOpts) (bool, error) {
    79  	if opts == nil {
    80  		return pk.Verify(msg, sig)
    81  	}
    82  	if opts.Hash == bccrypto.HASH_TYPE_SM3 && pk.Type() == bccrypto.SM2 {
    83  		uid := opts.UID
    84  		if len(uid) == 0 {
    85  			uid = bccrypto.CRYPTO_DEFAULT_UID
    86  		}
    87  		if sig == nil {
    88  			return false, fmt.Errorf("nil signature")
    89  		}
    90  		return pk.verifyWithSM3(msg, sig, uid), nil
    91  	}
    92  	dgst, err := hash.Get(opts.Hash, msg)
    93  	if err != nil {
    94  		return false, err
    95  	}
    96  	return pk.Verify(dgst, sig)
    97  }
    98  
    99  // ToStandardKey nolint
   100  func (pk *PublicKey) ToStandardKey() crypto.PublicKey {
   101  	der, err := MarshalPublicKey(pk)
   102  	if err != nil {
   103  		fmt.Println("failed to MarshalPublicKey, err = " + err.Error())
   104  	}
   105  	pub, err := tjx509.ParseSm2PublicKey(der)
   106  	if err != nil {
   107  		fmt.Println("failed to ParseSm2PublicKey, err = " + err.Error())
   108  	}
   109  	return pub
   110  }
   111  
   112  // PublicKey implements bccyrpto.PublicKey
   113  var _ bccrypto.EncryptKey = (*PublicKey)(nil)
   114  
   115  func (pk *PublicKey) EncryptWithOpts(data []byte, opts *bccrypto.EncOpts) ([]byte, error) {
   116  	return pk.Encrypt(data)
   117  }
   118  
   119  func (pk *PublicKey) Encrypt(plaintext []byte) ([]byte, error) {
   120  	return pk.PublicKey.Encrypt("sm2encrypt-with-sm3", plaintext, nil)
   121  }