fabric 链上数据防篡改

216 阅读2分钟

近日,因为工作需要,对 fabric 数据防篡改机制进行了研究,这里提供了一种验证链上数据防篡改的场景以供参考

基本思路:

进入某个peer节点修改本地的 Couch DB 数据,修改完后再调用链码发送一笔交易,发现执行结果是该 peer 节点的数据重新变为修改前的数据,说明篡改数据失败,系统具有放篡改能力。

具体操作如下,为了简化操作,直接借助官方使用 couchdb 样例,链码为 mymarble

先进入 firstnetwork 目录,执行以下命令起一个使用 couchdb 的byfn网络

./byfn.sh up -c mychannel -s couchdb  

然后进入客户端

docker exec -it cli bash  
export CHANNEL_NAME=mychannel  

执行以下命令

# peer0.org1 安装链码  
  
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp  
CORE_PEER_ADDRESS=peer0.org1.example.com:7051  
CORE_PEER_LOCALMSPID="Org1MSP"  
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt  
peer chaincode install -n mymarble -v 1.0.0 -p github.com/chaincode/marbles02/go  
  
# peer1.org1 安装链码  
  
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp  
CORE_PEER_ADDRESS=peer1.org1.example.com:8051  
CORE_PEER_LOCALMSPID="Org1MSP"  
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt  
peer chaincode install -n mymarble -v 1.0.0 -p github.com/chaincode/marbles02/go  
  
# peer0.org2 安装链码  
  
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp  
CORE_PEER_ADDRESS=peer0.org2.example.com:9051  
CORE_PEER_LOCALMSPID="Org2MSP"  
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  
peer chaincode install -n mymarble -v 1.0.0 -p github.com/chaincode/marbles02/go  
  
# peer1.org2 安装链码  
  
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp  
CORE_PEER_ADDRESS=peer1.org2.example.com:10051  
CORE_PEER_LOCALMSPID="Org2MSP"  
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt  
peer chaincode install -n mymarble -v 1.0.0 -p github.com/chaincode/marbles02/go  
  
  
# 实例化链链码  
  
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mymarble -v 1.0.0 -c '{"Args":["init"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"  
  
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mymarble --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["initMarble","marble1","blue","35","tom"]}'  
  

此时打开浏览器 http://localhost:5984/_utils/

进入 peer0.org1 (对外暴露端口为5984)的 couchdb,查看 marble1 变量:

{  
"_id": "marble1",  
"_rev": "1-1d12a3e8f79f5c0e40cc73c43701a6ba",  
"color": "blue",  
"docType": "marble",  
"name": "marble1",  
"owner": "tom",  
"size": 35,  
"~version": "\u0000CgMBBgA="  
}  

我们可以看到在 couchdb 中保存了 marble1 的各个字段的属性。

然后手动将其中的 35 改为25,并保存(试图通过修改peer本地的couchdb中的数据实现篡改数据的操作)。

此时在终端调用以下链码,即将 marble1 给 jerry

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mymarble --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["transferMarble","marble1","jerry"]}'  
注意此时指定的背书节点为 peer0.org1 和 peer0.org2

发现调用失败,返回背书不满足
这主要是因为 peer0.org1 的 couchdb 的数据已经改变,和 peer0.org1 的数据不同,导致模拟执行失败

此时,将其中一个背书节点背书节点 peer0.org1 替换成 peer1.org1,此时再次调用链码

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mymarble --peerAddresses peer1.org1.example.com:8051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["transferMarble","marble1","jerry"]}'  

链码调用成功

再次进入peer0.org1的couchdb,对外暴露端口为5984

http://localhost:5984/_utils/

发现此时 marble1 的owner 已经变为jerry,并且仍然是35

{  
"_id": "marble1",  
"_rev": "3-c2280ec7b75f7f5536b490acf10515a0",  
"color": "blue",  
"docType": "marble",  
"name": "marble1",  
"owner": "jerry",  
"size": 35,  
"~version": "\u0000CgMBBwA="  
}  

说明试图篡改数据的操作失败,系统具有防篡改能力