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 }