Fabric go sdk初始化所需證書解析


fabric sdk go 提供的官方文檔少之又少,要想入門,主要就靠研究官方的e2e系列示例,這真的是一件挺無奈的事情。沒法子,只能硬着頭皮上了。研究發現,e2e這個例子是通過cryptogen生成網絡所需的所有證書及密鑰的。一旦你按着操作后,你會發現你被大堆目錄淹沒,不知所措,根本不知道他們都是干嘛的。

那么,這篇文章的作用,就是告訴你,他們都是干嘛的,哪些是初始化sdk所需的。

讓我們開始吧!

生成證書配置

首先,用於生成證書目錄的配置文件crypto-config.yaml內容如下所示

# "OrdererOrgs" - Definition of organizations managing orderer nodes
OrdererOrgs:
  - Name: Mango
    Domain: mango.com
    # Specs is an array of Spec entries.  Each Spec entry consists of two fields : Hostname and CommonName
    Specs:
      - Hostname: orderer
# "PeerOrgs" - Definition of organizations managing peer nodes
PeerOrgs:
  - Name: Mango
    Domain: mango.com
    # Allows for the definition of 1 or more hosts that are created sequentially
    # from a template. By default, this looks like "peer%d" from 0 to Count-1.
    # You may override the number of nodes (Count), the starting index (Start)
    # or the template used to construct the name (Hostname).
    Template:
      Count: 2

證書目錄解析

我們根據上述配置來生成證書

mkdir -p crypto-config
./bin/cryptogen generate --config=./crypto-config.yaml

每個目錄和對應文件的功能如下:

crypto-config
├── ordererOrganizations
│   └── mango.com # domain
│       ├── ca
│       │   ├── ca.mango.com-cert.pem
│       │   └── ed9854ea794ed178750ab5fff0b8f7a4c4938721e85de25a65e171dac4dadf41_sk
│       ├── msp
│       │   ├── admincerts
│       │   │   └── Admin@mango.com-cert.pem
│       │   ├── cacerts
│       │   │   └── ca.mango.com-cert.pem
│       │   └── tlscacerts
│       │       └── tlsca.mango.com-cert.pem
│       ├── orderers
│       │   └── orderer.mango.com
│       │       ├── msp
│       │       │   ├── admincerts
│       │       │   │   └── Admin@mango.com-cert.pem
│       │       │   ├── cacerts
│       │       │   │   └── ca.mango.com-cert.pem
│       │       │   ├── keystore
│       │       │   │   └── b1ee6269b624746f682843f566dcfdbb9b1318ea36d605becc13843f52d13e2c_sk
│       │       │   ├── signcerts
│       │       │   │   └── orderer.mango.com-cert.pem
│       │       │   └── tlscacerts
│       │       │       └── tlsca.mango.com-cert.pem
│       │       └── tls
│       │           ├── ca.crt
│       │           ├── server.crt
│       │           └── server.key
│       ├── tlsca
│       │   ├── 30fe7e37c6b416049d567b99d07d4d0fca282d28cf51819a8ba9cb12a4b1b5c1_sk
│       │   └── tlsca.mango.com-cert.pem
│       └── users
│           └── Admin@mango.com
│               ├── msp
│               │   ├── admincerts
│               │   │   └── Admin@mango.com-cert.pem
│               │   ├── cacerts
│               │   │   └── ca.mango.com-cert.pem
│               │   ├── keystore
│               │   │   └── 749735ce27f18879efa1ffdf76bf9d800ccb0298c826cee2c2d68217eb731610_sk
│               │   ├── signcerts
│               │   │   └── Admin@mango.com-cert.pem
│               │   └── tlscacerts
│               │       └── tlsca.mango.com-cert.pem
│               └── tls
│                   ├── ca.crt
│                   ├── client.crt
│                   └── client.key
└── peerOrganizations
    └── org1.mango.com
        ├── ca  # 存放組織的根證書和對應的私鑰文件,默認采用EC算法,證書為自簽名。組織內的實體將基於該證書作為證書根。
        │   ├── 2c3c2cde48c8f1b5eb0fd54e0b1865d6b5bc3269ebba8cb5ac5a7dfbbd303367_sk
        │   └── ca.org1.mango.com-cert.pem
        ├── msp # 存放代表該組織的身份信息。
        │   ├── admincerts # 組織管理員的身份驗證證書,被根證書簽名。
        │   │   └── Admin@org1.mango.com-cert.pem
        │   ├── cacerts # 組織的根證書,同ca目錄下文件。
        │   │   └── ca.org1.mango.com-cert.pem
        │   └── tlscacerts # 用於TLS的ca證書,自簽名。
        │       └── tlsca.org1.mango.com-cert.pem
        ├── peers # 存放屬於該組織的所有peer節點。
        │   ├── peer0.org1.mango.com # 第一個peer的信息,包括其msp證書和TLS證書兩類。
        │   │   ├── msp
        │   │   │   ├── admincerts # 組織管理員的身份驗證證書。peer將基於這些證書來認證交易簽署這是否為管理員身份。
        │   │   │   │   └── Admin@org1.mango.com-cert.pem
        │   │   │   ├── cacerts # 組織的根證書.
        │   │   │   │   └── ca.org1.mango.com-cert.pem
        │   │   │   ├── keystore # 本節點的身份私鑰,用來簽名。
        │   │   │   │   └── d35fbb340c84ad06ffd6d58addaf694a62e23adf53066b9a287f86edbf6dd476_sk
        │   │   │   ├── signcerts # 驗證本節點簽名的證書,被組織根證書簽名。
        │   │   │   │   └── peer0.org1.mango.com-cert.pem
        │   │   │   └── tlscacerts # TLS連接用的身份證書,即組織TLS證書。
        │   │   │       └── tlsca.org1.mango.com-cert.pem
        │   │   └── tls # 存放tls相關的證書和私鑰
        │   │       ├── ca.crt # 組織的根證書
        │   │       ├── server.crt # 驗證本節點簽名的證書,被組織根證書簽名。
        │   │       └── server.key # 本節點的身份私鑰,用來簽名。
        │   └── peer1.org1.mango.com # 第二個peer的信息,結構類似。(省略)
        │       ├── msp
        │       │   ├── admincerts
        │       │   │   └── Admin@org1.mango.com-cert.pem
        │       │   ├── cacerts
        │       │   │   └── ca.org1.mango.com-cert.pem 
        │       │   ├── keystore
        │       │   │   └── ecfeefdab7f95113064a00227d7af5cb3ae448ec1334a932f768010b95dc32f3_sk
        │       │   ├── signcerts
        │       │   │   └── peer1.org1.mango.com-cert.pem
        │       │   └── tlscacerts
        │       │       └── tlsca.org1.mango.com-cert.pem
        │       └── tls
        │           ├── ca.crt
        │           ├── server.crt
        │           └── server.key
        ├── tlsca 存放組織tls連接用的根證書和私鑰文件。(TLS是傳輸層安全協議,其實就是SSL,現在叫TLS了)
        │   ├── 65b65931318b4aa19ae15d1da75413c68371d1506237311fc7244c8e46c1ba8a_sk
        │   └── tlsca.org1.mango.com-cert.pem # TLS根證書
        └── users 存放屬於該組織的用戶的實體。
            └── Admin@org1.mango.com # 管理員用戶的信息,包括其msp證書和tls證書兩類。
                ├── msp
                │   ├── admincerts # 組織根證書作為管理者身份驗證證書。
                │   │   └── Admin@org1.mango.com-cert.pem 
                │   ├── cacerts # 組織的根證書.
                │   │   └── ca.org1.mango.com-cert.pem 
                │   ├── keystore # 本用戶的身份私鑰,用來簽名。
                │   │   └── 22e70042f7dd79f35ea92a285d2377a673163805f85c9bf160c87de82db52a4c_sk
                │   ├── signcerts # 管理員用戶的身份驗證證書,被組織根證書簽名。要被某個Peer認可,則必須放到該peer的msp/admincerts下。
                │   │   └── Admin@org1.mango.com-cert.pem
                │   └── tlscacerts # TLS連接用的身份證書,即組織TLS證書。
                │       └── tlsca.org1.mango.com-cert.pem 
                └── tls # 存放tls相關的證書和私鑰
                    ├── ca.crt # 組織的根證書
                    ├── client.crt # 管理員的用戶身份驗證證書,被組織根證書簽名。
                    └── client.key # 管理員用戶的身份私鑰,用來簽名。

證書目錄精簡

一大堆文件是不是?其實經過分析后,可以發現,很多目錄的證書或者密鑰都是重復的。真正用到的主要是

  • 組織中 Admin用戶的證書和密鑰
  • 組織中的tls證書

如果你啟用了其他用戶,比如User1之類的,就還會有User1@mango.com這樣的目錄

精簡目錄

讓我們刪除多余目錄,精簡后目錄如下所示:

fixtures/crypto/
├── ordererOrganizations
│   └── mango.com
│       ├── tlsca
│          └── tlsca.org1.mango.com-cert.pem
└── peerOrganizations
    └── org1.mango.com
        ├── tlsca
        │   └── tlsca.org1.mango.com-cert.pem
        └── users
            └── Admin@org1.mango.com
                └── msp
                    ├── keystore
                    │   └── 22e70042f7dd79f35ea92a285d2377a673163805f85c9bf160c87de82db52a4c_sk
                    └── signcerts
                        └── Admin@org1.mango.com-cert.pem

怎么樣,是不是清爽多了。

證書目錄再精簡

本節內容依個人業務差異,僅供參考

我們發現證書的路徑六面都帶有mango.com這樣的ID字段,不方便重用,我們可以選擇去除這些ID,精簡目錄。

此外,密鑰文件22e70042f7dd79f35ea92a285d2377a673163805f85c9bf160c87de82db52a4c_sk名稱前面還有一長串的字符,看上去很奇怪是不是。這個一長串的字符,其實就是ski。我們也可以去除這個ski。

當然,如果你直接去除這些東西,那么sdk會報找不到響應文件的錯誤,所以我們需要去修改sdk源碼。

主要修改的文件如下:

fabric-go-sdk/pkg/msp/filecertstore.go

原先代碼

// NewFileCertStore ...
func NewFileCertStore(cryptoConfigMSPPath string) (core.KVStore, error) {
	_, orgName := path.Split(path.Dir(path.Dir(path.Dir(cryptoConfigMSPPath))))
	opts := &keyvaluestore.FileKeyValueStoreOptions{
		Path: cryptoConfigMSPPath,
		KeySerializer: func(key interface{}) (string, error) {
			ck, ok := key.(*msp.IdentityIdentifier)
			if !ok {
				return "", errors.New("converting key to CertKey failed")
			}
			if ck == nil || ck.MSPID == "" || ck.ID == "" {
				return "", errors.New("invalid key")
			}

			// TODO: refactor to case insensitive or remove eventually.
			r := strings.NewReplacer("{userName}", ck.ID, "{username}", ck.ID)
			certDir := path.Join(r.Replace(cryptoConfigMSPPath), "signcerts")
			return path.Join(certDir, fmt.Sprintf("%s@%s-cert.pem", ck.ID, orgName)), nil
		},
	}
	return keyvaluestore.New(opts)
}

修改后代碼

// NewFileCertStore ...
func NewFileCertStore(cryptoConfigMSPPath string) (core.KVStore, error) {
	opts := &keyvaluestore.FileKeyValueStoreOptions{
		Path: cryptoConfigMSPPath,
		KeySerializer: func(key interface{}) (string, error) {
			ck, ok := key.(*msp.IdentityIdentifier)
			if !ok {
				return "", errors.New("converting key to CertKey failed")
			}
			if ck == nil || ck.MSPID == "" || ck.ID == "" {
				return "", errors.New("invalid key")
			}
			// TODO: refactor to case insensitive or remove eventually.
			// 文件夾去除Mspid名稱
			r := strings.NewReplacer("{userName}", ck.ID)
			certDir := path.Join(r.Replace(cryptoConfigMSPPath), "signcerts")
			// 文件名精簡為cert.pem
			return path.Join(certDir, "cert.pem"), nil
		},
	}
	return keyvaluestore.New(opts)
}

fabric-go-sdk/pkg/msp/filecertstore.go

原先代碼

// NewFileKeyStore ...
func NewFileKeyStore(cryptoConfigMSPPath string) (core.KVStore, error) {
	opts := &keyvaluestore.FileKeyValueStoreOptions{
		Path: cryptoConfigMSPPath,
		KeySerializer: func(key interface{}) (string, error) {
			pkk, ok := key.(*msp.PrivKeyKey)
			if !ok {
				return "", errors.New("converting key to PrivKeyKey failed")
			}
			if pkk == nil || pkk.MSPID == "" || pkk.ID == "" || pkk.SKI == nil {
				return "", errors.New("invalid key")
			}

			// TODO: refactor to case insensitive or remove eventually.
			r := strings.NewReplacer("{userName}", pkk.ID, "{username}", pkk.ID)
			keyDir := path.Join(r.Replace(cryptoConfigMSPPath), "keystore")

			return path.Join(keyDir, hex.EncodeToString(pkk.SKI)+"_sk"), nil
		},
	}
	return keyvaluestore.New(opts)
}

修改后代碼

// NewFileKeyStore ...
func NewFileKeyStore(cryptoConfigMSPPath string) (core.KVStore, error) {
	opts := &keyvaluestore.FileKeyValueStoreOptions{
		Path: cryptoConfigMSPPath,
		KeySerializer: func(key interface{}) (string, error) {
			pkk, ok := key.(*msp.PrivKeyKey)
			if !ok {
				return "", errors.New("converting key to PrivKeyKey failed")
			}
			if pkk == nil || pkk.MSPID == "" || pkk.ID == "" || pkk.SKI == nil {
				return "", errors.New("invalid key")
			}

			// TODO: refactor to case insensitive or remove eventually.
			r := strings.NewReplacer("{userName}", pkk.ID, "{username}", pkk.ID)
			keyDir := path.Join(r.Replace(cryptoConfigMSPPath), "keystore")
			// 文件名統一為_sk
			return path.Join(keyDir, "_sk"), nil
		},
	}
	return keyvaluestore.New(opts)
}

再次精簡后的目錄

如此修改后,對應的證書目錄,我們就可以改成如下所示:

fixtures/crypto/
├── ordererOrganizations
│   └── tlsca
│       └── tlsca-cert.pem
└── peerOrganizations
    ├── tlsca
    │   └── tlsca-cert.pem
    └── users
        └── Admin
            └── msp
                ├── keystore
                │   └── _sk
                └── signcerts
                    └── cert.pem

怎么樣,是不是又精簡了很多?

初始化SDK配置文件

最后附上相應的初始化sdk所需的config.yaml文件

name: "mango-service-network"
#
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
#
version: 1.0.0
#
# The client section used by GO SDK.
#
client:

  # Which organization does this application instance belong to? The value must be the name of an org
  # defined under "organizations"
  organization: org1

  logging:
    level: info

  # Global configuration for peer, event service and orderer timeouts
  # if this this section is omitted, then default values will be used (same values as below)
#  peer:
#    timeout:
#      connection: 10s
#      response: 180s
#      discovery:
#        # Expiry period for discovery service greylist filter
#        # The channel client will greylist peers that are found to be offline
#        # to prevent re-selecting them in subsequent retries.
#        # This interval will define how long a peer is greylisted
#        greylistExpiry: 10s
#  eventService:
#    # Event service type (optional). If not specified then the type is automatically
#    # determined from channel capabilities.
#    type: (deliver|eventhub)
    # the below timeouts are commented out to use the default values that are found in
    # "pkg/fab/endpointconfig.go"
    # the client is free to override the default values by uncommenting and resetting
    # the values as they see fit in their config file
#    timeout:
#      connection: 15s
#      registrationResponse: 15s
#  orderer:
#    timeout:
#      connection: 15s
#      response: 15s
#  global:
#    timeout:
#      query: 180s
#      execute: 180s
#      resmgmt: 180s
#    cache:
#      connectionIdle: 30s
#      eventServiceIdle: 2m
#      channelConfig: 30m
#      channelMembership: 30s
#      discovery: 10s
#      selection: 10m

  # Root of the MSP directories with keys and certs.
  cryptoconfig:
    path: ${GOPATH}/src/github.com/hyperledger/fabric-sdk-go-api/fixtures/crypto

  # Some SDKs support pluggable KV stores, the properties under "credentialStore"
  # are implementation specific
  credentialStore:
    path: /tmp/mango-service-store

    # [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations
    # requiring a key store. PKCS#11 based implementations does not.
    cryptoStore:
      path: /tmp/mango-service-msp

   # 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

    # [Optional]. Client key and cert for TLS handshake with peers and orderers
    client:
      keyfile:
      certfile:

#
# [Optional]. But most apps would have this section so that channel objects can be constructed
# based on the content below. If an app is creating channels, then it likely will not need this
# section.
#
channels:
  # name of the channel
  mychannel:
    # Required. list of orderers designated by the application to use for transactions on this
    # channel. This list can be a result of access control ("org1" can only access "ordererA"), or
    # operational decisions to share loads from applications among the orderers.  The values must
    # be "names" of orgs defined under "organizations/peers"
    # deprecated: not recommended, to override any orderer configuration items, entity matchers should be used.
    # orderers:
    #  - orderer.example.com

    # Required. list of peers from participating orgs
    peers:
      peer0.org1.mango.com:
        # [Optional]. will this peer be sent transaction proposals for endorsement? The peer must
        # have the chaincode installed. The app can also use this property to decide which peers
        # to send the chaincode install request. Default: true
        endorsingPeer: true

        # [Optional]. will this peer be sent query proposals? The peer must have the chaincode
        # installed. The app can also use this property to decide which peers to send the
        # chaincode install request. Default: true
        chaincodeQuery: true

        # [Optional]. will this peer be sent query proposals that do not require chaincodes, like
        # queryBlock(), queryTransaction(), etc. Default: true
        ledgerQuery: true

        # [Optional]. will this peer be the target of the SDK's listener registration? All peers can
        # produce events but the app typically only needs to connect to one to listen to events.
        # Default: true
        eventSource: true

      peer1.org1.mango.com:

    policies:
      #[Optional] options for retrieving channel configuration blocks
      queryChannelConfig:
        #[Optional] min number of success responses (from targets/peers)
        minResponses: 1
        #[Optional] channel config will be retrieved for these number of random targets
        maxTargets: 1
        #[Optional] retry options for query config block
        retryOpts:
          #[Optional] number of retry attempts
          attempts: 5
          #[Optional] the back off interval for the first retry attempt
          initialBackoff: 500ms
          #[Optional] the maximum back off interval for any retry attempt
          maxBackoff: 5s
          #[Optional] he factor by which the initial back off period is exponentially incremented
          backoffFactor: 2.0


#
# list of participating organizations in this network
#
organizations:
  org1:
    mspid: org1.mango.com
    cryptoPath: peerOrganizations/users/{userName}/msp
    peers:
      - peer0.org1.mango.com
      - peer1.org1.mango.com

    # [Optional]. Certificate Authorities issue certificates for identification purposes in a Fabric based
    # network. Typically certificates provisioning is done in a separate process outside of the
    # runtime network. Fabric-CA is a special certificate authority that provides a REST APIs for
    # dynamic certificate management (enroll, revoke, re-enroll). The following section is only for
    # Fabric-CA servers.
    certificateAuthorities:
      - ca.org1.mango.com

#
# List of orderers to send transaction and channel create/update requests to. For the time
# being only one orderer is needed. If more than one is defined, which one get used by the
# SDK is implementation specific. Consult each SDK's documentation for its handling of orderers.
#
orderers:
  orderer.mango.com:
    url: localhost:7050

    # these are standard properties defined by the gRPC library
    # they will be passed in as-is to gRPC client constructor
    grpcOptions:
      ssl-target-name-override: orderer.mango.com
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: ${GOPATH}/src/github.com/hyperledger/fabric-sdk-go-api/fixtures/crypto/ordererOrganizations/tlsca/tlsca-cert.pem
#
# List of peers to send various requests to, including endorsement, query
# and event listener registration.
#
peers:
  peer0.org1.mango.com:
    # this URL is used to send endorsement and query requests
    url: localhost:7051
    # eventUrl is only needed when using eventhub (default is delivery service)
    eventUrl: localhost:7053

    grpcOptions:
      ssl-target-name-override: peer0.org1.mango.com
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: ${GOPATH}/src/github.com/hyperledger/fabric-sdk-go-api/fixtures/crypto/peerOrganizations/tlsca/tlsca-cert.pem

  peer1.org1.mango.com:
    # this URL is used to send endorsement and query requests
    url: localhost:8051
    # eventUrl is only needed when using eventhub (default is delivery service)
    eventUrl: localhost:8053

    grpcOptions:
      ssl-target-name-override: peer1.org1.mango.com
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: ${GOPATH}/src/github.com/hyperledger/fabric-sdk-go-api/fixtures/crypto/peerOrganizations/tlsca/tlsca-cert.pem


entityMatchers:
  peer:
    - pattern: (\w*)peer0.org1.mango.com(\w*)
      urlSubstitutionExp: localhost:7051
      eventUrlSubstitutionExp: localhost:7053
      sslTargetOverrideUrlSubstitutionExp: peer0.org1.mango.com
      mappedHost: peer0.org1.mango.com

    - pattern: (\w*)peer1.org1.mango.com(\w*)
      urlSubstitutionExp: localhost:8051
      eventUrlSubstitutionExp: localhost:8053
      sslTargetOverrideUrlSubstitutionExp: peer1.org1.mango.com
      mappedHost: peer1.org1.mango.com

  orderer:
    - pattern: (\w*)orderer.mango.com(\w*)
      urlSubstitutionExp: localhost:7050
      sslTargetOverrideUrlSubstitutionExp: orderer.mango.com
      mappedHost: orderer.mango.com

當然,這部分內容,也是存在優化空間的,還沒研究那么深入,后面有空再改。

參考文章

搭建基於hyperledger fabric的聯盟社區(八) --Fabric證書解析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM