Tendermint-I-ABCI介绍
aditosoftware/nodepki: NodePKI is a simple NodeJS based PKI manager for small corporate environments. (github.com)](https://github.com/WillZhuang/nodepki) NodePKI 是一个简单的基于 NodeJS 的 PKI 管理器,适用于小型企业环境。
1 | git clone https://github.com/aditosoftware/nodepki.git |
配置文件的例子有 config.yml.default,将其内容copy至 NodePKI/data/config/config.yml。修改 config.yml 根据你的配置。config.yml 中的密码将用于创建PKI。
1 | node server.js |
启动后,CA 文件将在 data/mypki 文件夹内创建。
1 | node nodepkictl useradd --username user1 --password user1password |
1 | node nodepkictl userdel --username user1 |
1 | curl -H "Content-type: application/json" -d '{ "data": { "state":"all" }, "auth": { "username":"thomas", "password":"test" } }' http://localhost:8080/api/v1/certificates/list |
1 | curl -H "Content-type: application/json" -d '{ "data": { "applicant":"Thomas", "csr":"---CERTIFICATE SIGNING REQUEST---", "lifetime":365, "type":"server" }, "auth": { "username":"thomas", "password":"test" } }' http://localhost:8080/api/v1/certificate/request |
NodePKI 服务器的简单命令行客户端。
1 | git clone https://github.com/ThomasLeister/nodepki-client.git |
Copy config.default.yml to config/config.yml and set the settings according to your environment.
1 | node client help |
Create new key + certificate from scratch and store both in out/ directory. Lifetime: 7 days.
1 | node client request --lifetime 7 --out out/ |
Create new key + certificate from scratch, add intermediate cert to cert and store in out/ directory
1 | node client request --out out/ --fullchain |
Lifetime defaults to cert_lifetime_default setting in config.yml
Create a new client certificate:
1 | node client request --type client --out out/ |
获取发布的证书
1 | node client list --state all |
可用的状态 Valid states:
1 | node client list --state valid |
… and store certificate to out/cert.pem
1 | node client get --serialnumber 324786EA --out out/cert.pem |
1 | node client revoke --cert cert.pem |
Get root certificate:
1 | node client getcacert --ca root |
Write root certificate to file:
1 | node client getcacert --ca root --out out/root.cert.pem |
Get intermediate certificate:
1 | node client getcacert --ca intermediate |
Get intermediate certificate + root certificate (=cert chain) and write to file:
1 | node client getcacert --ca intermediate --chain --out out/ca-chain.cert.pem |
虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 1978 年,由 RSA 算法的发明者的 R 和 A 以及 Dertouzos 提出。具体的定义如下:
A way to delegate processing of your data, without giving away access to it.
翻译成人话就是传统的加密方法和数据处理方法是互斥的,比如我需要计算两个数字的和(1 和 2),如果加密了之后,就无法对密文进行计算;如果想要进行计算,就必须知道这两个数字是 1 和 2。如果数据拥有方和计算方是同一方,那么知道 1 和 2 没啥问题;但如果数据拥有方和计算方并非同一方,并且数据拥有方还不想让计算方知道这两个数字是 1 和 2,这个时候就是同态加密发挥作用的时候了。
同态加密将数据的处理和数据本身解耦了:计算方拿到的是加密之后的密文,但是依然可以相加,相加之后把结果告诉数据拥有方,最终数据拥有方解密就可以知道最终的计算结果。
同态加密的这个特点使得云服务厂商非常在意,因为这一举解决了用户担心云服务厂商窃取数据的担心(因为加密了除了计算没法做其他事情),并且因为加密计算本身耗费更多计算资源,还可以变相提高营收。
总结一下:同态加密使得数据可以在加密的状态下进行计算,至于支持什么计算,如何进行计算,我们接下来继续讲。
EncData = Encrypt(Key, Data)F()Evaluate(F(), EncData) = Encrypt(Key, F(Data)),记为 ProEncDataProEncData 发回给到我F(Data) = Decrypt(Key, ProEncData),也就是最终结果在以上六个步骤中,至少有四个函数是必须的:
F(),是唯一由云平台运行的函数根据支持的 F() 的不同,同态加密分成了两类:
F() 都可以,只要这个算法能够被计算机实现即可。不过这个计算开销非常大,目前暂无实际应用。F() (比如只支持加法/乘法,并且只能执行有限次数)。这个方案有比较大的限制,但也因此计算开销较小,已经可以在实际中使用接下来我们会详细看看 Paillier 算法和 RSA 算法,对加法同态和乘法同态有更加深入的理解。
总共有如下几个步骤:
参考项目:
https://github.com/apple/swift-homomorphic-encryption
苹果公司表示,它正在使用同态加密技术进行实时来电者身份验证查询,用以支持来电者识别和垃圾电话拦截服务。这项技术允许苹果通过向服务器发送加密的查询,请求获取电话号码的相关信息,而服务器无需知道或存储电话号码。
苹果公司表示,典型的同态加密工作流可能是这样的:
https://github.com/homenc/HElib
IBM 提供的 HElib目前不再进行积极的开发,尽管还有一些未解决的问题,它现在处于“维护模式”,主要的工作是修复安全漏洞。
https://github.com/microsoft/SEAL
至于微软的 SEAL 库,自 2018 年以来也都没有与发布相关的新闻,尽管其 GitHub 代码库偶尔还会有一些更新。
项目地址:data61/MP-SPDZ: Versatile framework for multi-party computation (github.com)
1)在ubuntu环境中,安装依赖包。
1 | apt-get install automake build-essential git libboost-dev libboost-thread-dev libntl-dev libsodium-dev libssl-dev libtool m4 python3 texinfo yasm |
2)使用git下载项目源码,注意不是二进制的release文件。
3)在项目目录中,编译代码。
1 | make -j 8 tldr |
4)试用并执行 the tutorial 教程,他是一个双方的、对恶意安全的教程。
1 | ➜ MP-SPDZ git:(master) ./compile.py tutorial |
1 | # Minikube 安装 v1.20.0 |
1 | # 执行以下指令下载 Hyperledger 命令列工具 |
以上脚本会在本地下载k8s部署需要的容器和可执行文件,云上的话需要准备的镜像如下:
1 | centos:latest |
用于测试的chaincode镜像,marbles是hyperledger官方给的一个sample,但是源码没有打镜像,这里其他人打的一个镜像,我们只是用来测试部署是否成功,之后会用我们开发的存证chaincode镜像替换
1 | paragones/chaincode-marbles:1.0 |
1 | # 创建一个名为 hyperledger 的 namespace |
下图为本范例的部署架构,所有hyperledger 所需节点皆部署于 k8s 中的 hyperledger namespace 当中。架构中包含的节点如下
| 节点 | 挂载路径 | 路径说明 | PVC | PV hostPath |
|---|---|---|---|---|
| orderer0 | /var/hyperledger/orderer/ | 存放凭证 | orderer0-pvc | ./fabric/orderer0 |
| orderer0 | /var/hyperledger/production | 持久化资料 | orderer0-persist-pvc | ./fabric/orderer0persist |
| orderer1 | /var/hyperledger/orderer/ | 存放凭证 | orderer1-pvc | ./fabric/orderer1 |
| orderer1 | /var/hyperledger/production | 持久化资料 | orderer1-persist-pvc | ./fabric/orderer1persist |
| orderer2 | /var/hyperledger/orderer/ | 存放凭证 | orderer2-pvc | ./fabric/orderer2 |
| orderer2 | /var/hyperledger/production | 持久化资料 | orderer2-persist-pvc | ./fabric/orderer2persist |
| Org1-Peer | /etc/hyperledger/fabric/ | 存放凭证 | peer0-org1-pvc | ./fabric/peer0org1 |
| Org1-Peer | /var/hyperledger/production | 持久化资料 | peer0-org1-persist-pvc | ./fabric/peer0org1persist |
| Org1-Peer-CLI | /opt/gopath/src/github.com/ hyperledger/fabric/peer/crypto/ | 存放凭证 | peer0-org1-pvc | ./fabric/peer0org1 |
| Org2-Peer | /etc/hyperledger/fabric/ | 存放凭证 | peer0-org2-pvc | ./fabric/peer0org2 |
| Org2-Peer | /var/hyperledger/production | 持久化资料 | peer0-org2-persist-pvc | ./fabric/peer0org2persist |
| Org2-Peer-CLI | /opt/gopath/src/github.com/ hyperledger/fabric/peer/crypto/ | 存放凭证 | peer0-org1-pvc | ./fabric/peer0org2 |
Hyperledger Fabric 于节点沟通时必须依赖凭证进行沟通,因此必须先签发凭证。在凭证的签发过程中可以使用两种方式签发凭证
在此范例中将以 cryptogen 命令列生成各节点所需凭证,以下为签发凭证的指令。可以查看 git repo 中的 crypto-config.yaml 为签发凭证设定文件,crypto-config则为签发结果。
1 | cryptogen generate --config=crypto-config.yaml --output ./crypto-config |
(notice:练习中,需要再次生成新的凭证设定文件时,需要将./crypto-config文件夹删除后,再行运行上述命令。否则凭证设定文件不会被更新覆盖!)
1 | configtxgen -profile TwoOrgsOrdererGenesis -channelID devchan -outputBlock ./channel-artifacts/genesis.block |
1 | # 产生Channel 所需档案 |
在前述三、四、五章节中我们已经准备了以下内容
由于 Hyperledger 之 container 必须先将以上档案放置至正确位置后 container 才能正常启动。但本次安装不使用NFS 预先将档案填入,而是先启临时的 container 同步档案。
在本步骤我们将启动两个用于填充档案的 container
| container 名称 | 说明 |
|---|---|
| orderer-bastion | 填充 orderer0-pvc,orderer1-pvc,orderer2-pvc 所需要的文档 |
| peer-bastion | 填充 peer0-org1-pvc,peer0-org2-pvc 所需要的文档 |
以下为同步文档的步骤
6.1 启动临时 container
1 | kubectl create -f /deploy-hyperledger-fabric-on-k8s/file-populate-bastion/ |
这个指令将会产生 pv/pvc/orderer-bastion/peer-bastion 这些资源
6.2 同步 Orderer 所需文档
1 | # 登录进入 orderer-bastion |
6.3 同步 Peer 所需要的文档
1 | # 登录进入 peer-bastion |
1 | # 启动 orderer cluster |
內含 orderer0,orderer1,orderer2 所需的 deployment 与 service 资源
1 | # 启动 org1 peer0 |
9.1 将 org1 peer0 加入 channel
1 | # 登录进入 cli pod |
1 | # 产生 channel 区块 |
运行成功后,log信息如下:
1 | /opt/gopath/src/github.com/hyperledger/fabric/peer # peer channel create -o orderer0:7050 -c mychannel -f ./scripts/channel-artifacts/channel.tx - |
1 | # 加入 channel |
运行成功后,log信息如下:
1 | /opt/gopath/src/github.com/hyperledger/fabric/peer # peer channel join -b mychannel.block |
1 | # 查看是否在 channel 当中 |
9.2 將 org2 peer0 加入 channel
1 | # 登录进入 cli pod |
运行成功后,log信息如下:
1 | /opt/gopath/src/github.com/hyperledger/fabric/peer # peer channel fetch 0 mychannel.block -c mychannel -o orderer0:7050 --tls --cafile $ORDERER_CA |
10.1 安装chaincode
‘marbles’ 链码作为范例
打包org1
1 | # 进入github的chaincode/packaging |
将org1 tar文档安装到peer cli pod中
1 | # 将marbles-org1.tgz放入peer pod |
打包org2,如打包or1一样的步骤,请修改connection.json中的address
1 | "address": "chaincode-marbles-org2.hyperledger:7052" |
依照下列打包步骤
1 | $ rm -f code.tar.gz |
至此,已完成外部链码设置。
10.2 部署”智能合约”
制作golang的alpine镜像文件
1 | $ docker build -t chaincode/marbles:1.0 . |
进入github中 chaincode\k8s ,找到org1-chaincode-deployment.yaml和org2-chaincode-deployment.yaml中的CHAINCODE_CCID
将yaml文件中的CHAINCODE_CCID更换成为对应的 chaincode 识别码
1 | # 部署 chaincode 到aks上 |
完成部署。
10.3审核链码的安装
请在peer-cli-org1/peer-cli-org2 这2个pod中允许链码的安装,记得修改CHAINCODE_CCID
※peer-cli-org1 及 peer-cli-org2的CHAINCODE_CCID 需要对应到各自的chaincode识别码
1 | $ peer lifecycle chaincode approveformyorg --channelID mychannel --name marbles --version 1.0 --init-required --package-id marbles:e001937433673b11673d660d142c722fc372905db87f88d2448eee42c9c63064 --sequence 1 -o orderer0:7050 --tls --cafile $ORDERER_CA --signature-policy "AND ('org1MSP.peer','org2MSP.peer') |
检查所有org允许状态
1 | $peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name marbles --version 1.0 --init-require |
至此,2个peer-cli都审核完毕。
之后提交到channel 中
1 | peer lifecycle chaincode commit -o orderer0:7050 --channelID mychannel --name marbles --version 1.0 --sequence 1 --init-required --tls true --cafile $ORDERER_CA --peerAddresses peer0-org1:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1/peers/peer0-org1/tls/ca.crt --peerAddresses peer0-org2:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2/peers/peer0-org2/tls/ca.crt --signature-policy "AND ('org1MSP.peer','org2MSP.peer')" |
10.4测试
1 | # 查询安装的链码 |
目前hyperledger不对外,请使用kubectl port-forward的方式连进去。
指令:
1 | kubectl port-forward ${pord-id} 7050:7050 |
参考 fabric-samples 中typescript所撰写的范例 ※另有java, go 语言的范例!!
以下为typerscript 范例:
1 |
|
上述为app.ts,此app.ts会读取connection.json档,此档用于定义peer url以及peer的tls凭证路径。
1 | { |
路径对应如下:
tls CA Cert: crypto-config\peerOrganizations\org1\tlsca\tlsca.org1-cert.pem
X509 certificate: crypto-config\peerOrganizations\org1\users\Admin@org1\msp\signcerts\Admin@org1-cert.pem
X509 privateKey: crypto-config\peerOrganizations\org1\users\Admin@org1\msp\keystore\priv_sk
[color=#d85887]
成功收到资料如图
部署 fabric 和 CA 与 Kubenetes 之上