【问题标题】:Identity management on Hyperledger FabricHyperledger Fabric 上的身份管理
【发布时间】:2019-06-12 07:34:29
【问题描述】:

我使用 Hyperledger Fabric 1.4.1 和最新版本的 fabric-contract-api 用于智能合约,fabric-client 用于管理通道创建和链码的低级 API,fabric-network 用于与对等方的交互.我已参考this sample 设置我的网络。

我已经在nodejs 中编写了一个基本的链代码包,并设置了一个简单的 1 org、1 peer、1 orderer 网络。第一步是连接到对等节点并使用fabric-ca-client 创建管理员身份。根据示例,使用的注册 ID 和密码为 adminadminpw。这取决于configuration used here

我用来创建和加入频道,然后安装和实例化链码的代码是

const CAClient = require('fabric-ca-client');
const client = require('fabric-client');
const User = client.User;
const fs = require('fs');
const path = require('path');
const basePath = path.resolve(__dirname, '../certs');
const readCryptoFile = filename => fs.readFileSync(path.resolve(basePath, filename)).toString();
const ccPath = path.resolve(__dirname, '../chaincode/src/ax-chaincode');
const url = require('url');
const http = require('http');

  let myClient = new client();
  const ordererConfig = {
    hostname: 'orderer0',
    url: 'grpc://localhost:7050',
    pem: readCryptoFile('ordererOrg.pem')
  };
  const orderer = myClient.newOrderer(ordererConfig.url, {
    pem: ordererConfig.pem,
    'ssl-target-name-override': ordererConfig.hostname
  });

  let peerConfig = {
    hostname: 'ax-peer',
    url: 'grpc://localhost:7051', // change to grpcs://ax-peer:7051 in some condition (no idea?)
    eventHubUrl: 'grpc://localhost:7053',
    pem: readCryptoFile('axOrg.pem')
  };
  const defaultPeer = myClient.newPeer(peerConfig.url, {
    pem: peerConfig.pem,
    'ssl-target-name-override': peerConfig.hostname
  });
  // console.log(defaultPeer);
  myClient.setStateStore(await client.newDefaultKeyValueStore({
    path: './ax-peer'
  }))

let url = 'http://localhost:7054'
    const ca = new CAClient(url, {
      verify: false
    });
    let enrollmentID = 'admin';
    let enrollmentSecret = 'adminpw';
    const enrollment = await ca.enroll({
      enrollmentID: 'admin',
      enrollmentSecret: 'adminpw'
    });
    user = new User(enrollmentID, myClient);
    // console.log(enrollment);
    await user.setEnrollment(enrollment.key, enrollment.certificate, 'AxOrgMSP');

上面将检查admin 用户是否在状态存储中可用。关于上述过程的一些疑问

  1. 假设只使用一个 CA,此处生成的管理员用户可用于与同一组织的任何和所有对等方进行交互?
  2. 此身份的实际用途是什么,因为对于其余功能,使用cryptogen 为每个对等方生成的管理员身份(代码如下)
  3. 在注册管理员时,ca.enroll() 中没有传递任何attrs,因此在查询身份时,roles 字段自然返回 null。共享的ca-server 链接清楚地为其分配了client, user, peer, validator, auditor 的角色。因为它使用adminadminpw 来注册 id 和 secret,所以这不应该反映在这里吗?

继续代码

  // crypto material got from cryptogen and shifted to new folder
  let adminUser = await myClient.createUser({
    username: `Admin@ax-peer`,
    mspid: 'AxOrgMSP',
    cryptoContent: {
      privateKeyPEM: readCryptoFile('Admin@ax-org-key.pem'),
      signedCertPEM: readCryptoFile('Admin@ax-org-cert.pem')
    }
  });
  let txId = myClient.newTransactionID();
  let envelope_bytes = fs.readFileSync('./channel.tx');
  let channelConfig = myClient.extractChannelConfig(envelope_bytes);
  let signature = myClient.signChannelConfig(channelConfig);
  const request = {
      name: 'default',
      orderer: orderer,
      config: channelConfig,
      signatures: [signature],
      txId: txId
    };
   const response = await myClient.createChannel(request); // should be 200
   // rest of code joins channel, installs and instantiates chaincode
   // docker logs show init function being called in new cc container

stateStore 中有两个文件(如预期的那样),称为adminAdmin@ax-peer。这些看起来像

"name": "Admin@ax-peer",
  "mspid": "AxOrgMSP",
  "roles": null,
  "affiliation": "",
  "enrollmentSecret": "",
  enrollment: {
    "signingIdentity": "554a5f5cfc5a59231a04b7b051bcbcb4f79c4226ff336a4aa48b551de4a8428f",
    "certificate": "-----BEGIN CERTIFICATE----- xyz -----END CERTIFICATE-----"
  }

await myClient.getUserContext('admin', true); 从状态存储中使用此用户时,客户端如何签署交易?我无法找到使用fabric-client SDK 创建的任何用户的私钥/证书。

现在如果我使用fabric-network API,将实现一个FileSystemWallet() 函数,该函数存储它为每个用户创建的私有和公共证书。

const enrollment = await ca.enroll({ enrollmentID: `admin`, enrollmentSecret: `adminpw` });
const identity = X509WalletMixin.createIdentity('AxOrgMSP', enrollment.certificate, enrollment.key.toBytes());
wallet.import('admin', identity);

此函数的用途与ca.enroll() 相同,但以可见的方式存储私有证书。如果我想在fabric-network SDK中使用fabric-client创建的用户,我需要转换证书,我该如何实现?

TLDR - 使用fabric-client 注册用户,然后使用fabric-network 中的Gateway() 类与同一用户提交交易。

非常感谢任何建议和指导。谢谢!

【问题讨论】:

    标签: hyperledger-fabric hyperledger hyperledger-fabric-ca hyperledger-fabric-sdk-js


    【解决方案1】:

    这个堆栈溢出问题太多了,所以我只想对您发布的内容有所了解。

    1. 您从ca服务器注册的管理员身份称为admin,因为它是fabric ca服务器的注册商,因此可以在ca服务器中注册更多的身份。它不是任何其他东西(例如结构网络)的管理员身份。
    2. 您已使用较低级别的 api 和 fabric-network 机制进行身份管理。在较低级别的 api 中,所有持久保存到文件系统的是状态存储,公共证书和私钥存储在内存中纯粹是因为您调用所有内容的方式只是碰巧以这种方式设置默认值,不幸的是其他方法使用低级 api 可能需要您使用 cryptoKeyStore 显式设置密码套件。在钱包实现中,您可能使用了文件系统钱包,因此所有内容都保存在文件系统中。

    如果可以的话,我的建议是从结构网络网关开始。然后,如果您需要下降到较低级别的 api,因为结构网络不能满足您的需要,那么您可以调用

    gateway.getClient()
    
    or
    
    network.getChannel()
    

    获取已预先配置了网关配置和身份的客户端/通道。 要访问证书颁发机构,您可以使用 gateway.getClient().getCertificateAuthority() 所有这些都允许您使用钱包实现进行身份管理(并且钱包实现提供了不同的持久性机制,例如在内存、文件系统、couchdb 中,或者您可以自己编写)

    【讨论】:

    • 谢谢。我会试试这个。虽然我在主目录 (Ubuntu) 中找到了一个名为 .hfc-key-store 的隐藏文件夹,该文件夹存储了与注册低级 API 的用户相对应的私钥。我浏览了fabric-clientfabric-ca-client 存储库,发现hfc-key-store 是默认存储位置。但这变得有点混乱,因为公共证书和私有密钥存储在两个单独的文件夹中。是的,我有很多问题,刚刚完成 PoC 并进入大规模试点,所以必须处理很多额外的事情。
    • 我还注意到生成的密钥不断变化,它不是基于注册 ID 和秘密的确定性,与公共区块链实现不同。
    • 每次注册时,您都会创建一个新的私钥,并从该私钥生成一个新证书。因此,每次您注册时,您都会获得一个不同的身份,而该身份恰好具有相同的通用名称。另请注意,如果您使用非临时 cryptoKeyStore,则私钥仅存储在 .hfc-key-store
    • 是的,我确保将true 放在持久性选项中。虽然有趣的是,所有来自网关的身份功能都传递给客户端实例,但是当从网关注册用户时,会保存证书、发布 prvt 密钥,而从客户端注册时只保存私钥和证书!
    猜你喜欢
    • 1970-01-01
    • 2020-09-24
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    • 2017-12-24
    • 1970-01-01
    相关资源
    最近更新 更多