Idemix(Identity Mixer)是一套协议加密组件,提供更强大的身份验证和隐私保护特性。
适用场景
用户发送交易时,需要隐藏自己的身份信息,并且不希望其他人通过追踪交易记录查找到自己发送的交易。即用户的保密要求比较严格,具体为用户在需要以下保密要求时,建议使用该功能:
- 匿名性(anonymity):不暴露交易者的身份;
- 无关联性(unlinkability):无法通过多个交易确定发送者身份,即一个身份发送多条交易不会暴露这些交易来自相同的身份。
原理
发行方(issuer)颁发给用户证书,认证用户的一些属性。
用户生成ZKP(zero-knowledge proof),证明自己拥有该证书,并选择性地暴露自己的部分属性;将此ZKP发送给验证方(verifier)即可。
具体在Fabric中,流程如下图所示:
由Fabric CA或Idemixgen工具为用户生成证书,SDK发送交易时提交用户的身份证明,MSP可以验证用户的身份, chaincode中可以获取用户暴露的身份属性。
Idemix证书等身份信息的签发过程类似X.509数字证书,都是对一组属性进行数字签名,该数字签名无法被伪造并且和私钥文件关联。同时,Idemix用零知识证明确保用户在某些属性上的签名有效。
Idemix技术基于盲签名方案,支持多个消息和签名拥有有效零知识证明。这保证了Idemix支持无关联性(unlinkability)。即使发行人也无法将证明关联到原始证书,发行人和验证者都不能判断两个证明是否来自同一证书。
*备注:盲签名(blind signature scheme)
性质:
1)签名者对其所签署的消息是不可见的,即签名者不知道他所签署消息的具体内容。
2)签名消息不可追踪,即当签名消息被公布后,签名者无法知道这是他哪次签署的。
模型:
接收者首先将待签数据进行盲变换,把变换后的盲数据发给签名者。
经签名者签名后再发给接收者。
接收者对签名再作去盲变换,得出的便是签名者对原数据的盲签名。
这样便满足了性质1)。
要满足性质2),必须使签名者事后看到盲签名时不能与盲数据联系起来,这通常是依靠某种协议来实现的。
实际操作:
- 使用Fabric CA或idemixgen工具生成签发者的私钥和证书等。
1)使用Fabric CA:Fabric CA server(>= Version 1.3)启动时会自动在主目录下生成相关的证书文件。启动命令如下:
fabric-ca-server init
也可以使用docker启动,启动后生成的文件目录结构如下:
fabric-ca-server
├── IssuerPublicKey
├── IssuerRevocationPublicKey
├── ca-cert.pem
├── fabric-ca-server-config.yaml
├── fabric-ca-server.db
└── msp
└── keystore
├── IssuerRevocationPrivateKey
├── IssuerSecretKey
└── ee8fe16f689fa3c5ad0b7de96366bde0f8c80478b83b5b09801af38af2779a8a_sk
2)使用idemixgen工具:生成签发者的私钥和证书等,使用如下命令(其中output参数指定证书存放路径):
idemixgen ca-keygen --output="idemix-config-dir"
生成文件的目录结构如下:
idemix-config-dir
├── ca
│ ├── IssuerPublicKey
│ ├── IssuerSecretKey
│ └── RevocationKey
└── msp
├── IssuerPublicKey
└── RevocationPublicKey
- 启动fabric环境之前,需要修改configtx.yaml文件,配置验证者的相关信息,具体添加内容如下:
- &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: idemix-config-dir
- 使用Fabric Java SDK提供的idemixEnroll接口为用户申请身份,然后可以使用和普通证书相同的方式发送交易。
此外,idemixgen也可以为用户生成签名文件,但是暂时没法使用命令行发送idemix签名的交易。生成命令如下:
idemixgen signerconfig –u ORG-UNIT –e ENROLLMENTID –r REVOCATIONHANDLE --output=idemix-config-dir
默认是member身份,如果想生成admin身份,加参数-a。
- chaincode中cid库提供函数GetAttributeValue可以获取身份的ou(organization unit,e.g. “org1.department1”)和role(e.g. “member”)信息,具体使用见如下代码【摘自官网】:
// 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))
}
局限性
- 目前只有Fabric Java SDK提供了相关API获取用户身份和发送交易,其他SDK暂不支持;
- 目前合约只有Golang提供了API获取用户身份的属性值;
- 目前只支持固定的属性,不支持自定义属性。具体支持的属性包括:Organizational Unit attribute (“ou”),Role attribute (“role”),Enrollment ID attribute,Revocation Handle attribute;
- 不支持证书的废除;
- peer并不使用Idemix背书,Idemix签名在Client SDK,peer仅支持验签。