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,实现用户注册完成。