github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/pwk_member.go (about) 1 package access_contoller 2 3 import ( 4 "crypto/sha256" 5 "encoding/hex" 6 "fmt" 7 bccrypto "github.com/bigzoro/my_simplechain/core/access_contoller/crypto" 8 "github.com/bigzoro/my_simplechain/core/access_contoller/crypto/asym" 9 "github.com/mr-tron/base58" 10 "sync" 11 ) 12 13 // an instance whose member type is a certificate 14 // 定义了一个区块链网络成员的核心属性,包括其身份、所属组织、公钥信息、角色和使用的哈希类型。 15 // 这样的设计使得区块链网络能够高效地进行身份验证、权限控制和数据完整性校验 16 type pkMember struct { 17 18 // pem public key 19 // 成员的唯一标识符,通常是基于成员的公钥信息生成的。这个ID可以用来在网络中唯一地标识这个成员 20 id string 21 22 // organization identity who owns this member 23 // orgId表示拥有这个成员的组织的标识符。在多组织的区块链网络中,这个字段用于区分成员属于哪个组织 24 orgId string 25 26 // public key uid 27 // uid是公钥的唯一标识符,用于在可能存在多个公钥的情况下区分不同的公钥 28 uid string 29 30 // the public key used for authentication 31 // 存储用于身份验证的公钥。在区块链网络中,公钥和私钥对用于签名和验证签名,以确保交易或消息的真实性和完整性 32 pk bccrypto.PublicKey 33 34 // role of this member 35 // role字段表示这个成员在网络中的角色。不同的角色可能有不同的权限和责任 36 role Role 37 38 // hash type from chain configuration 39 // hashType字段指定了链配置中使用的哈希类型。哈希函数用于生成数据的哈希值,是区块链技术中确保数据不可篡改的关键机制之一 40 hashType string 41 } 42 43 func (pm *pkMember) GetPk() bccrypto.PublicKey { 44 return pm.pk 45 } 46 47 // GetMemberId returns the identity of this member (non-uniqueness) 48 func (pm *pkMember) GetMemberId() string { 49 return pm.id 50 } 51 52 // GetOrgId returns the organization id which this member belongs to 53 func (pm *pkMember) GetOrgId() string { 54 return pm.orgId 55 } 56 57 // GetRole returns roles of this member 58 func (pm *pkMember) GetRole() Role { 59 return pm.role 60 } 61 62 // GetUid returns the identity of this member (unique) 63 func (pm *pkMember) GetUid() string { 64 return pm.uid 65 } 66 67 func newPkMemberFromAcs(member *Member, adminList, consensusList *sync.Map, 68 acs *accessControlService) (*pkMember, error) { 69 70 // 检查成员类型是否为公钥,如果不是则返回错误 71 if member.MemberType != MemberType_PUBLIC_KEY { 72 return nil, fmt.Errorf("new public key member failed: memberType and authType do not match") 73 } 74 75 // 尝试从成员信息中解析公钥,如果解析失败则返回 76 pk, err := asym.PublicKeyFromPEM(member.MemberInfo) 77 if err != nil { 78 return nil, fmt.Errorf("new public key member failed: parse the public key from PEM failed") 79 } 80 81 // 获取公钥的字节表示 82 pkBytes, err := pk.Bytes() 83 if err != nil { 84 return nil, fmt.Errorf("new public key member failed: %s", err.Error()) 85 } 86 87 // 尝试从管理员列表中加载公钥对应的管理员成员,如果存在,则创建并返回一个新的公钥成员实例 88 adminMember, ok := adminList.Load(hex.EncodeToString(pkBytes)) 89 if ok { 90 admin, _ := adminMember.(*adminMemberModel) 91 return newPkMemberFromParam(admin.orgId, admin.pkBytes, RoleAdmin, acs.hashType) 92 } 93 94 // 如果公钥不是管理员,则尝试创建与公钥关联的 libp2p 节点 ID 95 //var nodeId string 96 //nodeId, err = CreateLibp2pPeerIdWithPublicKey(pk) 97 //if err != nil { 98 // return nil, fmt.Errorf("new public key member failed: create libp2p peer id with pk failed") 99 //} 100 // 101 //// 尝试从共识列表中加载节点 ID 对应的共识成员,如果存在,则创建并返回一个新的成员实例 102 //consensusMember, ok := consensusList.Load(nodeId) 103 //if ok { 104 // consensus, _ := consensusMember.(*consensusMemberModel) 105 // return newPkMemberFromParam(consensus.orgId, pkBytes, RoleConsensusNode, acs.hashType) 106 //} 107 108 // 如果公钥既不是管理员也不是共识成员,则尝试从链上读取公钥信息 109 //publicKeyIdex := pubkeyHash(pkBytes) 110 //publicKeyInfoBytes, err := acs.dataStore.ReadObject(syscontract.SystemContract_PUBKEY_MANAGE.String(), 111 // []byte(publicKeyIdex)) 112 //if err != nil { 113 // return nil, fmt.Errorf("new public key member failed: %s", err.Error()) 114 //} 115 116 // 如果链上不存在该公钥信息,则返回错误 117 //if publicKeyInfoBytes == nil { 118 // return nil, fmt.Errorf("new public key member failed: the public key doesn't belong to a member on chain") 119 //} 120 121 // 解析链上的公钥信息 122 //var publickInfo PKInfo 123 //err = proto.Unmarshal(publicKeyInfoBytes, &publickInfo) 124 //if err != nil { 125 // return nil, fmt.Errorf("new public key member failed: %s", err.Error()) 126 //} 127 // 128 //// 根据链上公钥信息创建并返回一个新的公钥成员实例 129 //return newPkMemberFromParam(publickInfo.OrgId, pkBytes, 130 // protocol.Role(publickInfo.Role), acs.hashType) 131 132 return nil, nil 133 } 134 135 // 定义函数newPkMemberFromParam,它接收一个组织ID、公钥字节、角色和哈希类型,返回一个公钥成员和可能的错误。 136 func newPkMemberFromParam(orgId string, pkBytes []byte, role Role, 137 hashType string) (*pkMember, error) { 138 139 // 尝试从哈希算法映射中查找给定的哈希类型 140 hash, ok := bccrypto.HashAlgoMap[hashType] 141 if !ok { 142 return nil, fmt.Errorf("sign failed: unsupport hash type") 143 } 144 145 // 初始化一个pkMember结构体实例。 146 var pkMem pkMember 147 pkMem.orgId = orgId 148 pkMem.hashType = hashType 149 150 // 尝试从公钥字节中解析公钥,如果失败,则返回错误。 151 pk, err := asym.PublicKeyFromDER(pkBytes) 152 if err != nil { 153 return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error()) 154 } 155 156 // 设置pkMember结构体的公钥和角色字段。 157 pkMem.pk = pk 158 pkMem.role = role 159 160 // 计算公钥的主题密钥标识符(SKI),这通常用于唯一标识公钥。 161 ski, err := ComputeSKI(hash, pk.ToStandardKey()) 162 if err != nil { 163 return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error()) 164 } 165 166 // 将SKI编码为十六进制字符串,并设置为pkMember的UID。 167 pkMem.uid = hex.EncodeToString(ski) 168 169 // 将公钥转换为PEM格式的字符串,如果失败,则返回错误。 170 pkPem, err := pk.String() 171 if err != nil { 172 return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error()) 173 } 174 175 // 设置pkMember的ID为公钥的PEM字符串。 176 pkMem.id = pkPem 177 178 // 返回初始化完成的pkMember实例和nil错误。 179 return &pkMem, nil 180 } 181 182 func pubkeyHash(pubkey []byte) string { 183 pkHash := sha256.Sum256(pubkey) 184 strPkHash := base58.Encode(pkHash[:]) 185 return strPkHash 186 } 187 188 //// CreateLibp2pPeerIdWithPublicKey create a peer.ID with crypto.PublicKey. 189 //func CreateLibp2pPeerIdWithPublicKey(publicKey crypto.PublicKey) (string, error) { 190 // pubKey, err := ParseGoPublicKeyToPubKey(publicKey.ToStandardKey()) 191 // if err != nil { 192 // return "", err 193 // } 194 // pid, err := libp2ppeer.IDFromPublicKey(pubKey) 195 // if err != nil { 196 // return "", err 197 // } 198 // return pid.Pretty(), err 199 //} 200 // 201 //// ParseGoPublicKeyToPubKey parse a go crypto PublicKey to a libp2p crypto PubKey. 202 //func ParseGoPublicKeyToPubKey(publicKey bccrypto.PublicKey) (libp2pcrypto.PubKey, error) { 203 // switch p := publicKey.(type) { 204 // case *ecdsa.PublicKey: 205 // if p.Curve == sm2.P256Sm2() { 206 // b, err := tjx509.MarshalPKIXPublicKey(p) 207 // if err != nil { 208 // return nil, err 209 // } 210 // pub, err := tjx509.ParseSm2PublicKey(b) 211 // if err != nil { 212 // return nil, err 213 // } 214 // return libp2pcrypto.NewSM2PublicKey(pub), nil 215 // } 216 // if p.Curve == btcec.S256() { 217 // return (*libp2pcrypto.Secp256k1PublicKey)(p), nil 218 // } 219 // return libp2pcrypto.NewECDSAPublicKey(p), nil 220 // 221 // case *sm2.PublicKey: 222 // return libp2pcrypto.NewSM2PublicKey(p), nil 223 // case *rsa.PublicKey: 224 // return libp2pcrypto.NewRsaPublicKey(*p), nil 225 // default: 226 // return nil, errors.New("unsupported public key type") 227 // } 228 //} 229 230 type signingPKMember struct { 231 // Extends Identity 232 pkMember 233 234 // Sign the message 235 sk bccrypto.PrivateKey 236 } 237 238 // Verify verifies a signature over some message using this member 239 func (pm *pkMember) Verify(hashType string, msg []byte, sig []byte) error { 240 hash, ok := bccrypto.HashAlgoMap[hashType] 241 if !ok { 242 return fmt.Errorf("cert member verify signature failed: unsupport hash type") 243 } 244 245 ok, err := pm.pk.VerifyWithOpts(msg, sig, &bccrypto.SignOpts{ 246 Hash: hash, 247 UID: bccrypto.CRYPTO_DEFAULT_UID, 248 }) 249 if err != nil { 250 return fmt.Errorf("cert member verify signature failed: [%s]", err.Error()) 251 } 252 if !ok { 253 return fmt.Errorf("cert member verify signature failed: invalid signature") 254 } 255 return nil 256 } 257 258 // When using public key instead of certificate, 259 // hashType is used to specify the hash algorithm while the signature algorithm is decided by the public key itself. 260 func (spm *signingPKMember) Sign(hashType string, msg []byte) ([]byte, error) { 261 hash, ok := bccrypto.HashAlgoMap[hashType] 262 if !ok { 263 return nil, fmt.Errorf("sign failed: unsupport hash type") 264 } 265 return spm.sk.SignWithOpts(msg, &bccrypto.SignOpts{ 266 Hash: hash, 267 UID: bccrypto.CRYPTO_DEFAULT_UID, 268 }) 269 } 270 271 // GetMember returns Member 272 func (pm *pkMember) GetMember() (*Member, error) { 273 memberInfo, err := pm.pk.String() 274 if err != nil { 275 return nil, fmt.Errorf("get pb member failed: %s", err.Error()) 276 } 277 return &Member{ 278 OrgId: pm.orgId, 279 MemberInfo: []byte(memberInfo), 280 MemberType: MemberType_PUBLIC_KEY, 281 }, nil 282 }