通过docker启动fabric ca,并通过java注册用户

发布时间 2023-04-14 11:17:41作者: Nichols1205

0.本文默认已生成身份信息文件,只是单纯的通过fabric网络中的ca机构进行用户的注册。生成身份信息文件的步骤可查看之前的随笔

1.编写ca的docker-compose文件

vim docker-compose-ca.yaml

文件内容如下:

version: '2.0'

networks:
  custom:

services:

  ca.org1.example.com:
    image: hyperledger/fabric-ca:1.5.6 # 修改为自己的版本
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-org1
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server/ca.org1.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server/priv_sk
      - FABRIC_CA_SERVER_DEBUG=true
        #- FABRIC_CA_SERVER_DB_TYPE=mysql
        #- FABRIC_CA_SERVER_DB_DATASOURCE=root:root@tcp(10.2.136.116:3306)/fabric_rca_org0?parseTime=true
    ports:
      - "7054:7054"
    command: sh -c 'fabric-ca-server start -b admin:adminpw  -d'
    volumes:
      - ../crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server # :前内容定位到自己的文件目录
    container_name: ca_peerOrg1
    networks:
      - custom

  ca.org2.example.com:
    image: hyperledger/fabric-ca:1.5.6
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-org2
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server/ca.org2.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server/priv_sk
      - FABRIC_CA_SERVER_DEBUG=true
      - FABRIC_CA_SERVER_DB_TYPE=mysql
      - FABRIC_CA_SERVER_DB_DATASOURCE=root:root@tcp(10.2.136.116:3306)/fabric_rca_org0?parseTime=true
    ports:
      - "8054:7054"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
    volumes:
      - ../crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server
    container_name: ca_peerOrg2
    networks:
      - custom

修改完成后启动docker-compose文件

docker-compose -f docker-compose-ca.yaml up -d

2.通过spring-boot进行用户的注册

文件目录如下:

 

 

pox.xml引入以下依赖:

<!--    fabric依赖    -->
        <dependency>
            <groupId>org.hyperledger.fabric-sdk-java</groupId>
            <artifactId>fabric-sdk-java</artifactId>
            <version>2.2.12</version>
        </dependency>

        <dependency>
            <groupId>org.hyperledger.fabric</groupId>
            <artifactId>fabric-gateway</artifactId>
            <version>1.0.1</version>
        </dependency>

其中model层创建AppUser、CACertResponse对象,如下:

package com.nichols.fabric_ca_ldap.model;

/**
 * @author nichols
 * @date 2023/4/3 11:29
 */

import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.User;

import java.io.Serializable;
import java.util.Set;

/**
 * Fabric user
 */
public class AppUser implements User, Serializable {
    private static final long serializationId = 1L;

    private String name;
    private Set<String> roles;
    private String account;
    private String affiliation;
    private Enrollment enrollment;
    private String mspId;

    public AppUser() {

    }

    public AppUser(String name, String affiliation, String mspId, Enrollment enrollment) {
        this.name = name;
        this.affiliation = affiliation;
        this.enrollment = enrollment;
        this.mspId = mspId;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public Set<String> getRoles() {
        return roles;
    }

    public void setRoles(Set<String> roles) {
        this.roles = roles;
    }

    @Override
    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    @Override
    public String getAffiliation() {
        return affiliation;
    }

    public void setAffiliation(String affiliation) {
        this.affiliation = affiliation;
    }

    @Override
    public Enrollment getEnrollment() {
        return enrollment;
    }

    public void setEnrollment(Enrollment enrollment) {
        this.enrollment = enrollment;
    }

    @Override
    public String getMspId() {
        return mspId;
    }

    public void setMspId(String mspId) {
        this.mspId = mspId;
    }

    @Override
    public String toString() {
        return "AppUser{" +
                "name='" + name + '\'' +
                ", roles=" + roles +
                ", account='" + account + '\'' +
                ", affiliation='" + affiliation + '\'' +
                ", enrollment=" + enrollment +
                ", mspId='" + mspId + '\'' +
                '}';
    }
}
package com.nichols.fabric_ca_ldap.model;

import java.security.PrivateKey;

/**
 * @author nichols
 * @date 2023/4/3 16:27
 */
public class CACertResponse {
    private PrivateKey privateKey;
    private String cert;

    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    public void setPrivateKey(PrivateKey privateKey) {
        this.privateKey = privateKey;
    }

    public String getCert() {
        return cert;
    }

    public void setCert(String cert) {
        this.cert = cert;
    }

    public CACertResponse() {
    }

    public CACertResponse(PrivateKey privateKey, String cert) {
        this.privateKey = privateKey;
        this.cert = cert;
    }
}

服务层创建service服务

package com.nichols.fabric_ca_ldap.service;


import com.nichols.fabric_ca_ldap.model.AppUser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;

/**
 * @author nichols
 * @date 2023/4/3 11:30
 */
@Service
public class FabricCaService {
    private final Logger log = LogManager.getLogger(FabricCaService.class);

    /**
     * 获取caClient
     * @param url CA的地址:示例:http://192.168.1.106:7054
     * @return caClient
     */
    public HFCAClient getCaClient(String url) {
        log.info("**********start**********");
        CryptoSuite cryptoSuite = null;
        HFCAClient  caClient = null;
        try {
            cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
            Properties prop = new Properties();
            prop.put("verity",false);
            caClient = HFCAClient.createNewInstance(url,prop);
            caClient.setCryptoSuite(cryptoSuite);
        }  catch (Exception e) {
            log.error(e);
            return null;
        }
        return caClient;
    }

    /**
     * 注册管理员
     * @param hfcaClient caClient
     * @param userName 管理员名称:admin
     * @param userSecret 管理员密码:adminpw
     * @param affiliation affiliation示例:org1
     * @param mspId 所属组织mspId 示例:Org1Msp
     * @return
     */
    public AppUser enrollAdmin(HFCAClient hfcaClient, String userName, String userSecret, String affiliation, String mspId) {
        AppUser admin = null;
        try {
            admin = tryDeserialize(userName);
            if (admin == null) {
                Enrollment adminEnrollment = null;
                adminEnrollment = hfcaClient.enroll(userName, userSecret);
                admin = new AppUser(userName, affiliation, mspId, adminEnrollment);
                serialize(admin);
            }
        } catch (Exception e) {
            log.error(e);
            return null;
        }
        return admin;
    }

    /**
     * 注册并登记用户
     * @param hfcaClient caClient
     * @param userName 注册用户用户名
     * @param affiliation 机构:org1
     * @param mspId 所属mspId like:Org1Msp
     * @param admin 管理员用户
     * @return
     */
    public AppUser registerAndEnrollUser(HFCAClient hfcaClient,String userName,String affiliation,String mspId,AppUser admin) {
        AppUser appUser = null;
        try {
            RegistrationRequest rr = new RegistrationRequest(userName, affiliation);
            String userSecret = hfcaClient.register(rr, admin);
            Enrollment userEnrollment = hfcaClient.enroll(userName, userSecret);
            appUser = new AppUser(userName, affiliation,mspId, userEnrollment);
        } catch (Exception e) {
            log.error(e);
            return null;
        }
        return appUser;
    }


     void serialize(AppUser appUser) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(
                Paths.get(appUser.getName() + ".jso")))) {
            oos.writeObject(appUser);
        }
    }

    /**
     * Deserialize AppUser object from file
     *
     * @param name The name of the user. Used to build file name ${name}.jso
     * @return
     * @throws Exception
     */
     AppUser tryDeserialize(String name) throws Exception {
        if (Files.exists(Paths.get(name + ".jso"))) {
            return deserialize(name);
        }
        return null;
    }

     AppUser deserialize(String name) throws Exception {
        try (ObjectInputStream decoder = new ObjectInputStream(
                Files.newInputStream(Paths.get(name + ".jso")))) {
            return (AppUser) decoder.readObject();
        }
    }
}

创建Controller对象或者Test类进行测试,如下:

package com.nichols.fabric_ca_ldap.controller;

import com.nichols.fabric_ca_ldap.model.AppUser;
import com.nichols.fabric_ca_ldap.model.CACertResponse;
import com.nichols.fabric_ca_ldap.service.CommonService;
import com.nichols.fabric_ca_ldap.service.FabricCaService;
import com.nichols.fabric_ca_ldap.util.IOUtil;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;


/**
 * @author nichols
 * @date 2023/4/3 11:32
 */
@Controller
@RequestMapping("/fabric_ca")
public class FabricCaController {
    @Autowired
    private FabricCaService fabricCaService;
//    @Autowired
//    private CommonService commonService;
//    private IOUtil IOUtils;

    @PostMapping("/registerUser")
    public @ResponseBody CACertResponse registerUsers(String registerUserName) throws IOException {
        // 获取caClient
        HFCAClient caClient = fabricCaService.getCaClient("http://192.168.66.129:7054");
        // 注册管理员
        AppUser admin = fabricCaService.enrollAdmin(caClient, "admin", "adminpw", "org1", "Org1MSP");
        // 注册用户
        AppUser appUser = fabricCaService.registerAndEnrollUser(caClient, registerUserName, "org1", "Org1MSP", admin);
        CACertResponse caCertResponse = new CACertResponse();
        caCertResponse.setPrivateKey(appUser.getEnrollment().getKey());
//        String privateKey = Base64.encodeBase64String(appUser.getEnrollment().getKey().getEncoded());
        caCertResponse.setCert(appUser.getEnrollment().getCert());
        PrivateKey privateKey = appUser.getEnrollment().getKey();
//        PublicKey publicKey = commonService.getPublicKeyByCertString(appUser.getEnrollment().getCert());
        // 获取 公钥和私钥 的 编码格式(通过该 编码格式 可以反过来 生成公钥和私钥对象)
//        byte[] priv_encoded = privateKey.getEncoded();
//        byte[] pub_encoded = publicKey.getEncoded();
        // 把 公钥和私钥 的 编码格式 转换为 Base64文本 方便保存
//        String pubEncBase64 = new BASE64Encoder().encode(pub_encoded);
//        String priEncBase64 = new BASE64Encoder().encode(priv_encoded);
//        String pubEncBase64 = new String(Base64.getEncoder().encode(pub_encoded));
//        String priEncBase64 = new String(Base64.getEncoder().encode(priv_encoded));
        // 保存 公钥和私钥 到指定文件
//        IOUtils.writeFile(pubEncBase64, new File("E://pub.txt"));
//        IOUtils.writeFile(priEncBase64, new File("E://pri.txt"));

//        String privateKey = Base64.encodeBase64String(appUser.getEnrollment().getKey().getEncoded());
//        caCertResponse.setCert(appUser.getEnrollment().getCert());
//        System.out.println(privateKey);
        System.out.println("*****PrivateKey*****");
        System.out.println(Base64.getEncoder().encode(appUser.getEnrollment().getKey().getEncoded()));
        System.out.println("*****PrivateKey*****");
        System.out.println("*****Cert*****");
        System.out.println(caCertResponse.getCert());
        System.out.println("*****Cert*****");
        return caCertResponse;
    }
}

至此,java使用spring-boot对接ca,实现用户注册完成。