fabric-ca的使用其实很多书上都有相关例子,但是用go-sdk的例子很少,而且go-sdk的文档也很少。折腾了一大圈,还看了官方的hyperledger fabric-go-sdk中测试用例才终于搞明白了。泪流满面。实际运行过程中也是各种错误,好在所有问题都解决了,分享给大家供参考,希望大家都能少走弯路。
注明:下面代码中action.sdk就是fabricsdk
需要导入的包
"github.com/hyperledger/fabric-sdk-go/pkg/client/msp"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
//EnrollUser enroll a user have registerd
func EnrollUser(username string, password string) (bool, error) {
ctx := sdk.Context()
mspClient, err := msp.New(ctx)
if err != nil {
fmt.Printf("Failed to create msp client: %s\n", err)
return true, err
}
_, err = mspClient.GetSigningIdentity(username)
if err == msp.ErrUserNotFound {
fmt.Println("Going to enroll user")
err = mspClient.Enroll(username, msp.WithSecret(password))
if err != nil {
fmt.Printf("Failed to enroll user: %s\n", err)
return true, err
}
fmt.Printf("Success enroll user: %s\n", username)
} else if err != nil {
fmt.Printf("Failed to get user: %s\n", err)
return false, err
}
fmt.Printf("User %s already enrolled, skip enrollment.\n", username)
return true, nil
}
//Register a new user with username , password and department.
func RegisterlUser(username, password, department string) error {
ctx := Context()
mspClient, err := msp.New(ctx)
if err != nil {
fmt.Printf("Failed to create msp client: %s\n", err)
}
request := &msp.RegistrationRequest{
Name: username,
Type: "user",
Affiliation: department,
Secret: password,
}
secret, err := mspClient.Register(request)
if err != nil {
fmt.Printf("register %s [%s]\n", username, err)
return err
}
fmt.Printf("register %s successfully,with password %s\n", username, secret)
return nil
}
再使用之前需要先初始化
sdk, err := fabsdk.New(config.FromFile(ConfigFile))
这里配置文件可以参考如下:
---
#
name: "golang-sdk-network"
version: 1.0.0
client:
organization: Org1
logging:
level: info
peer:
timeout:
connection: 3s
queryResponse: 45s
executeTxResponse: 30s
eventService:
timeout:
connection: 3s
registrationResponse: 3s
orderer:
timeout:
connection: 3s
response: 5s
cryptoconfig:
path: ${CRYPTO_CONFIG_PATH}
# Some SDKs support pluggable KV stores, the properties under "credentialStore"
# are implementation specific
credentialStore:
# [Optional]. Used by user store. Not needed if all credentials are embedded in configuration
# and enrollments are performed elswhere.
path: "/tmp/fabric-client-kv-supply.com-org1"
# [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations
# requiring a key store. PKCS#11 based implementations does not.
cryptoStore:
# Specific to the underlying KeyValueStore that backs the crypto key store.
path: "/tmp/fabric-client-crypto-kv-supply.com-org1"
# [Optional] BCCSP config for the client. Used by GO SDK.
BCCSP:
security:
enabled: true
default:
provider: "SW"
hashAlgorithm: "SHA2"
softVerify: true
level: 256
tlsCerts:
# [Optional]. Use system certificate pool when connecting to peers, orderers (for negotiating TLS) Default: false
systemCertPool: false
channels:
# name of the channel
mychannel:
policies:
queryChannelConfig:
minResponses: 1
maxTargets: 1
retryOpts:
attempts: 5
initialBackoff: 500ms
maxBackoff: 5s
backoffFactor: 2.0
discovery:
maxTargets: 2
retryOpts:
attempts: 4
initialBackoff: 500ms
maxBackoff: 5s
backoffFactor: 2.0
eventService:
resolverStrategy: PreferOrg
balancer: Random
blockHeightLagThreshold: 5
reconnectBlockHeightLagThreshold: 8
peerMonitorPeriod: 6s
peers:
peer0.org1.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer1.org1.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer2.org1.supply.com:
endorsingPeer: true
eventSource: true
chaincodeQuery: true
ledgerQuery: true
peer0.org2.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer1.org2.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer2.org2.supply.com:
endorsingPeer: true
eventSource: true
chaincodeQuery: true
ledgerQuery: true
peer0.org3.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer1.org3.supply.com:
endorsingPeer: false
eventSource: false
chaincodeQuery: true
ledgerQuery: true
peer2.org3.supply.com:
endorsingPeer: true
eventSource: true
chaincodeQuery: true
ledgerQuery: true
chaincodes:
# the format follows the "cannonical name" of chaincodes by fabric code
- test_cc:v1.0
organizations:
Org1:
mspid: Org1MSP
cryptoPath: "peerOrganizations/org1.supply.com/users/{username}@org1.supply.com/msp"
peers:
- peer0.org1.supply.com
- peer1.org1.supply.com
- peer2.org1.supply.com
certificateAuthorities:
- ca-org1
Org2:
mspid: Org2MSP
cryptoPath: "peerOrganizations/org2.supply.com/users/{username}@org2.supply.com/msp"
peers:
- peer0.org2.supply.com
- peer1.org2.supply.com
- peer2.org2.supply.com
certificateAuthorities:
- ca-org2
Org3:
mspid: Org3MSP
cryptoPath: "peerOrganizations/org3.supply.com/users/{username}@org3.supply.com/msp"
peers:
- peer0.org3.supply.com
- peer1.org3.supply.com
- peer2.org3.supply.com
certificateAuthorities:
- ca-org3
OrdererOrg:
mspID: OrdererMSP
cryptoPath: "ordererOrganizations/supply.com/users/{username}@supply.com/msp"
orderers:
orderer0.supply.com:
url: grpcs://10.61.0.92:7055
grpcOptions:
ssl-target-name-override: orderer0.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/ordererOrganizations/supply.com/tlsca/tlsca.supply.com-cert.pem
#
# List of peers to send various requests to, including endorsement, query
# and event listener registration.
#
peers:
peer0.org1.supply.com:
url: grpcs://10.61.0.92:7056
eventUrl: grpcs://10.61.0.92:7058
grpcOptions:
ssl-target-name-override: peer0.org1.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/tlsca/tlsca.org1.supply.com-cert.pem
peer1.org1.supply.com:
url: grpcs://10.61.0.92:7066
eventUrl: grpcs://10.61.0.92:7068
grpcOptions:
ssl-target-name-override: peer1.org1.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/tlsca/tlsca.org1.supply.com-cert.pem
peer2.org1.supply.com:
url: grpcs://10.61.0.92:7076
eventUrl: grpcs://10.61.0.92:7078
grpcOptions:
ssl-target-name-override: peer2.org1.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/tlsca/tlsca.org1.supply.com-cert.pem
peer0.org2.supply.com:
url: grpcs://10.61.0.92:7556
eventUrl: grpcs://10.61.0.92:7558
grpcOptions:
ssl-target-name-override: peer0.org2.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/tlsca/tlsca.org2.supply.com-cert.pem
peer1.org2.supply.com:
url: grpcs://10.61.0.92:7566
eventUrl: grpcs://10.61.0.92:7568
grpcOptions:
ssl-target-name-override: peer1.org2.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/tlsca/tlsca.org2.supply.com-cert.pem
peer2.org2.supply.com:
url: grpcs://10.61.0.92:7576
eventUrl: grpcs://10.61.0.92:7578
grpcOptions:
ssl-target-name-override: peer2.org2.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/tlsca/tlsca.org2.supply.com-cert.pem
peer0.org3.supply.com:
url: grpcs://10.61.0.92:8056
eventUrl: grpcs://10.61.0.92:8058
grpcOptions:
ssl-target-name-override: peer0.org3.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/tlsca/tlsca.org3.supply.com-cert.pem
peer1.org3.supply.com:
url: grpcs://10.61.0.92:8066
eventUrl: grpcs://10.61.0.92:8068
grpcOptions:
ssl-target-name-override: peer1.org3.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/tlsca/tlsca.org3.supply.com-cert.pem
peer2.org3.supply.com:
url: grpcs://10.61.0.92:8076
eventUrl: grpcs://10.61.0.92:8078
grpcOptions:
ssl-target-name-override: peer2.org3.supply.com
keep-alive-time: 0s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/tlsca/tlsca.org3.supply.com-cert.pem
certificateAuthorities:
ca-org1:
url: https://ca.org1.supply.com:7059
httpOptions:
verify: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/ca/ca.org1.supply.com-cert.pem
client:
key:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.key
cert:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca-org1
ca-org2:
url: https://ca.org2.supply.com:7559
httpOptions:
verify: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/ca/ca.org2.supply.com-cert.pem
client:
key:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/users/[email protected]/tls/client.key
cert:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org2.supply.com/users/[email protected]/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca-org2
ca-org3:
url: https://ca.org3.supply.com:8059
httpOptions:
verify: false
tlsCACerts:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/ca/ca.org3.supply.com-cert.pem
client:
key:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/users/[email protected]/tls/client.key
cert:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org3.supply.com/users/[email protected]/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca-org3
entityMatchers:
orderer:
- pattern: orderer0.supply.com
urlSubstitutionExp: 10.61.0.92:7055
sslTargetOverrideUrlSubstitutionExp: orderer0.supply.com
mappedHost: orderer0.supply.com
- pattern: (\w+).supply.com
urlSubstitutionExp: 10.61.0.92:7055
sslTargetOverrideUrlSubstitutionExp: orderer0.supply.com
mappedHost: orderer0.supply.com
我在实际中遇到的错误如下:
通过go-sdk向fabric ca注册时出现下面错误(我的fabric-ca是跑在docker里的)
http: TLS handshake error from 10.61.0.89:24542: remote error: tls: bad certificate
在客户端显示
post https://ca.org1.supply.com:7059/enroll: x509: certificate signed by unknown authority
我修改了docker启动ca时的命令如下:
environment:
- FABRIC_CA_SERVER_CA_NAME=ca-org1
- FABRIC_CA_TLS_ENABLED=true
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.supply.com-cert.pem
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/00764da16f825ec232b3da10b7c041b0b61634f1fa3aaa9a64742c78b49797bd_sk
ports:
- "7059:7054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.supply.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/00764da16f825ec232b3da10b7c041b0b61634f1fa3aaa9a64742c78b49797bd_sk -b admin:adminpw -d'
然后修改了配置文件中tlsCACerts.(这里官方给的例子中是tlsca/tlsca.org1.supply.com-cert.pem)
certificateAuthorities:
ca-org1:
url: https://ca.org1.supply.com:7059
httpOptions:
verify: false
tlsCACerts:
path: /tmp/yang/config/crypto-config/peerOrganizations/org1.supply.com/ca/ca.org1.supply.com-cert.pem
client:
key:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.key
cert:
path: ${CRYPTO_CONFIG_PATH}/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.crt
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca-org1
向fabric-ca发送请求时出现如下错误
Post https://10.61.0.89:7059/enroll: x509: cannot validate certificate for 10.61.0.89 because it doesn't contain any IP SANs
]
配置文件中要把ca的url写成域名而不是ip,如下:
certificateAuthorities:
ca-org1:
url: https://ca.org1.supply.com:7059
httpOptions:
verify: false
–tls.certfiles /tmp/yang/config/crypto-config/peerOrganizations/org1.supply.com/ca/ca.org1.supply.com-cert.pem
–tls.client.certfile /tmp/yang/config/crypto-config/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.key
/tmp/yang/config/crypto-config/peerOrganizations/org1.supply.com/users/[email protected]/tls/client.crt
/root/.fabric-ca-client/cacerts/ca-org1-supply-com-7059.pem