Fabric 1.3中的新增的idemixer(Identity Mixer)以前不大懂zero-knowledge proof(零知识证明),原本觉得PKI基础的MSP是比较常用和稳健的方式,新加个验证方式是不是有点增加复杂性。
最近有时间整理下,才发现零知识证明也真是个黑科技。
网上这篇文章写得蛮好的http://www.elecfans.com/blockchain/1015964.html
这里以Fabric给出的例子: 假设Alice需要向Bob(门店职员)证明她DMV(车管所)颁发的合法驾照。这个场景,Alice就是下图的user/用户, DMV车管所则是issuer/证书颁发者, Bob则是verifier验证者。
Alice为了证明自己是合法的司机,大多时候她会把自己的驾照交给Bob检查和验证,但这样做Bob就可以知道Alice的很多额外的隐私信息,例如名字,地址,年龄等。
如果使用idemixer和零正式证明的方式, 我们只允许Bob知道当前这个女用户是个合法的司机,其它信息都保密。 即使下次Alice再来门店,Alice应该提供给Bob不同的证明,保证Bob不会知道这个证明是同一个用户。
即零知识证明可提供匿名性和无关联性。
elecfans的文章总结得很好了,常见的是以下两点。
- 数据隐私保护和身份验证,如Alice和Bob的例子所示,
- 减少计算和扩容,同样的多次计算可以使用零知识证明压缩和减少,最新的以太坊可是大力推崇
具体参看https://hyperledger-fabric.readthedocs.io/en/latest/idemixgen.html
(1) Fabric CA配置 fabric-ca-server init
会生成IssuerPublicKey和IssuerRevocationPublicKey两个文件
(2) MSP初始化配置 configtx.yaml定义Org1Idemix和Org2Idemix两个组织, 注意msptype类型为idemix, mspdir对应文件应使用Fabric CA生成的IssuerPublicKey和IssuerRevocationPublicKey构成。
Organizations:
- &Org1Idemix
# defaultorg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
name: idemixMSP1
# id to load the msp definition as
id: idemixMSPID1
msptype: idemix
mspdir: crypto-config/peerOrganizations/org3.example.com
- &Org2Idemix
# defaultorg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
name: idemixMSP2
# id to load the msp definition as
id: idemixMSPID2
msptype: idemix
mspdir: crypto-config/peerOrganizations/org4.example.com
profiles:
TwoOrgsOrdererGenesis_v13:
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
- *Org1Idemix
- *Org2Idemix
Application:
<<: *ApplicationDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *ApplicationCapabilities1_3
TwoOrgsChannel_v13:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
- *Org1Idemix
- *Org2Idemix
Capabilities:
<<: *ApplicationCapabilities1_3
(3) CA客户端生成用户
IdemixEnrollment idemixEnrollment = hfcaClient.idemixEnroll(x509enrollment, "idemixMSPID1");
(4)验证者链码如何获取idemixer信息 暂时go的链码的cid(Client Identity)库才支持获取idemixer证书信息。
func GetAttributeValue(stub ChaincodeStubInterface, attrName string) (value string, found bool, err error)
type ChaincodeStubInterface interface {
// GetCreator returns `SignatureHeader.Creator` (e.g. an identity)
// of the `SignedProposal`. This is the identity of the agent (or user)
// submitting the transaction.
GetCreator() ([]byte, error)
}
type ClientIdentity interface {
// GetID returns the ID associated with the invoking identity. This ID
// is guaranteed to be unique within the MSP.
GetID() (string, error)
// Return the MSP ID of the client
GetMSPID() (string, error)
// GetAttributeValue returns the value of the client's attribute named `attrName`.
// If the client possesses the attribute, `found` is true and `value` equals the
// value of the attribute.
// If the client does not possess the attribute, `found` is false and `value`
// equals "".
GetAttributeValue(attrName string) (value string, found bool, err error)
// AssertAttributeValue verifies that the client has the attribute named `attrName`
// with a value of `attrValue`; otherwise, an error is returned.
AssertAttributeValue(attrName, attrValue string) error
// GetX509Certificate returns the X509 certificate associated with the client,
// or nil if it was not identified by an X509 certificate.
GetX509Certificate() (*x509.Certificate, error)
}
暂时idemixer的GetAttributeValue只支持ou和role
- ou 是identity’s affiliation (e.g. “org1.department1”)
- role 是‘member’ 或 ‘admin’.
具体调用的go链码
package main
import (
"fmt"
"log"
"os"
"strconv"
"strings"
"github.com/hyperledger/fabric-chaincode-go/pkg/cid"
"github.com/hyperledger/fabric-chaincode-go/shim"
pb "github.com/hyperledger/fabric-protos-go/peer"
)
// Invoke makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
Info.Println("########### example_cc Invoke ###########")
function, args := stub.GetFunctionAndParameters()
// Getting attributes from an idemix credential
ou, found, err := cid.GetAttributeValue(stub, "ou");
if err != nil {
return shim.Error("Failed to get attribute 'ou'")
}
if !found {
return shim.Error("attribute 'ou' not found")
}
if !strings.HasSuffix(ou, "department1") {
return shim.Error(fmt.Sprintf("Incorrect 'ou' returned, got '%s' expecting to end with 'department1'", ou))
}
role, found, err := cid.GetAttributeValue(stub, "role");
if err != nil {
return shim.Error("Failed to get attribute 'role'")
}
if !found {
return shim.Error("attribute 'role' not found")
}
if role != "member" {
return shim.Error(fmt.Sprintf("Incorrect 'role' returned, got '%s' expecting 'member'", role))
}
if function == "delete" {
// Deletes an entity from its state
return t.delete(stub, args)
}
if function == "query" {
// queries an entity state
return t.query(stub, args)
}
if function == "move" {
// Deletes an entity from its state
return t.move(stub, args)
}
Error.Printf("Unknown action, check the first argument, must be one of 'delete', 'query', or 'move'. But got: %v", args[0])
return shim.Error(fmt.Sprintf("Unknown action, check the first argument, must be one of 'delete', 'query', or 'move'. But got: %v", args[0]))
}
还不大完善,基本现阶段还是推荐用传统的MSP方式,具体参考https://hyperledger-fabric.readthedocs.io/en/latest/idemix.html#current-limitations
零知识证明在以太坊是推崇的,它的应用场景实际蛮广的,fabric尚需努力,不过貌似2.0那么久还没release或者是推广得不好。不过区块链的前途是光明的,道路是曲折的,多了解下这些基础不是坏事。
本文分享自 Hyperledger实践 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!