github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/tencentcloudkms/key.go (about) 1 /* 2 Copyright (C) THL A29 Limited, a Tencent company. All rights reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package tencentcloudkms 8 9 import ( 10 "crypto" 11 "encoding/base64" 12 "fmt" 13 14 bccrypto "chainmaker.org/chainmaker/common/v2/crypto" 15 "chainmaker.org/chainmaker/common/v2/crypto/hash" 16 "chainmaker.org/chainmaker/common/v2/json" 17 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" 18 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" 19 kms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms/v20190118" 20 "github.com/tjfoc/gmsm/sm2" 21 "github.com/tjfoc/gmsm/sm3" 22 ) 23 24 type PrivateKey struct { 25 kms *kms.Client 26 keyType string 27 keyId string 28 keyAlias string 29 pubKey bccrypto.PublicKey 30 } 31 32 func (sk *PrivateKey) Type() bccrypto.KeyType { 33 return sk.PublicKey().Type() 34 } 35 36 func (sk *PrivateKey) Bytes() ([]byte, error) { 37 keyConfig := KMSPrivateKeyConfig{ 38 KeyType: sk.keyType, 39 KeyId: sk.keyId, 40 KeyAlias: sk.keyAlias, 41 } 42 return json.Marshal(keyConfig) 43 } 44 45 func (sk *PrivateKey) String() (string, error) { 46 skBytes, err := sk.Bytes() 47 if err != nil { 48 return "", err 49 } 50 return string(skBytes), nil 51 } 52 53 func (sk *PrivateKey) PublicKey() bccrypto.PublicKey { 54 return sk.pubKey 55 } 56 57 func (sk *PrivateKey) Sign(data []byte) ([]byte, error) { 58 msgBase64 := base64.StdEncoding.EncodeToString(data) 59 60 request := kms.NewSignByAsymmetricKeyRequest() 61 62 request.Algorithm = common.StringPtr(sk.keyType) 63 request.MessageType = common.StringPtr(MODE_DIGEST) 64 request.KeyId = common.StringPtr(sk.keyId) 65 request.Message = common.StringPtr(msgBase64) 66 67 response, err := sk.kms.SignByAsymmetricKey(request) 68 if _, ok := err.(*errors.TencentCloudSDKError); ok { 69 return nil, fmt.Errorf("KMS API error: %s", err) 70 } 71 if err != nil { 72 return nil, err 73 } 74 75 sig, err := base64.StdEncoding.DecodeString(*(response.Response.Signature)) 76 if err != nil { 77 return nil, err 78 } 79 80 return sig, nil 81 } 82 83 func (sk *PrivateKey) SignWithOpts(msg []byte, opts *bccrypto.SignOpts) ([]byte, error) { 84 if opts == nil { 85 return sk.Sign(msg) 86 } 87 if opts.Hash == bccrypto.HASH_TYPE_SM3 && sk.Type() == bccrypto.SM2 { 88 pkSM2, ok := sk.PublicKey().ToStandardKey().(*sm2.PublicKey) 89 if !ok { 90 return nil, fmt.Errorf("SM2 private key does not match the type it claims") 91 } 92 uid := opts.UID 93 if len(uid) == 0 { 94 uid = bccrypto.CRYPTO_DEFAULT_UID 95 } 96 97 za, err := sm2.ZA(pkSM2, []byte(uid)) 98 if err != nil { 99 return nil, fmt.Errorf("PKCS11 error: fail to create SM3 digest for msg [%v]", err) 100 } 101 e := sm3.New() 102 e.Write(za) 103 e.Write(msg) 104 dgst := e.Sum(nil)[:32] 105 106 return sk.Sign(dgst) 107 } 108 dgst, err := hash.Get(opts.Hash, msg) 109 if err != nil { 110 return nil, err 111 } 112 return sk.Sign(dgst) 113 } 114 115 func (sk *PrivateKey) ToStandardKey() crypto.PrivateKey { 116 return &Signer{sk} 117 }