Published on

fabric-ca搭建 sdk使用

Authors

前置条件

  • unbuntu 18.04
  • fabric-ca-server 1.4.6

安装

  • 源码安装
  • 二进制安装

我直接用二进制,方便点。 hyperledger-fabric-ca-linux-amd64-1.4.6.tar.gz下载地址

下载完后得到

 bin/
├── fabric-ca-client
└── fabric-ca-server

将这两个可执行文件加入环境变量 PATH.

设置fabric ca server的HOME目录

1.通过 --home参数设置 2.如果设置了FABRIC_CA_SERVER_HOME环境变量,则使用该环境变量作为主文件夹。 3.如果设置了FABRIC_CA_HOME环境变量,则使用该环境变量作为主文件夹。 4.如果设置了CA_CFG_PATH环境变量,则使用该环境变量作为主文件夹。 如果以上方法都没有设置,则将当前工作目录作为主文件夹。

启动fabric-ca-server

直接运行

fabric-ca-server start -b admin:adminpw --tls.enabled

因为tls证书问题,请运行下面这条命令

fabric-ca-server start -b admin:adminpw --tls.enabled --csr.hosts 192.168.128.129

打印如下日志。

2020/04/27 01:51:57 [INFO] Created default configuration file at /home/t/ca02_demo/fabric-ca-server-config.yaml
2020/04/27 01:51:57 [INFO] Starting server in home directory: /home/t/ca02_demo
2020/04/27 01:51:57 [INFO] Server Version: 1.4.6
2020/04/27 01:51:57 [INFO] Server Levels: &{Identity:2 Affiliation:1 Certificate:1 Credential:1 RAInfo:1 Nonce:1}
2020/04/27 01:51:57 [WARNING] &{69 The specified CA certificate file /home/t/ca02_demo/ca-cert.pem does not exist}
2020/04/27 01:51:57 [INFO] generating key: &{A:ecdsa S:256}
2020/04/27 01:51:57 [INFO] encoded CSR
2020/04/27 01:51:57 [INFO] signed certificate with serial number 596481663851329572374858418792394216370550593268
2020/04/27 01:51:57 [INFO] The CA key and certificate were generated for CA
2020/04/27 01:51:57 [INFO] The key was stored by BCCSP provider 'SW'
2020/04/27 01:51:57 [INFO] The certificate is at: /home/t/ca02_demo/ca-cert.pem
2020/04/27 01:51:58 [INFO] Initialized sqlite3 database at /home/t/ca02_demo/fabric-ca-server.db
2020/04/27 01:51:58 [INFO] The issuer key was successfully stored. The public key is at: /home/t/ca02_demo/IssuerPublicKey, secret key is at: /home/t/ca02_demo/msp/keystore/IssuerSecretKey
2020/04/27 01:51:58 [INFO] Idemix issuer revocation public and secret keys were generated for CA ''
2020/04/27 01:51:58 [INFO] The revocation key was successfully stored. The public key is at: /home/t/ca02_demo/IssuerRevocationPublicKey, private key is at: /home/t/ca02_demo/msp/keystore/IssuerRevocationPrivateKey
2020/04/27 01:51:58 [INFO] Home directory for default CA: /home/t/ca02_demo
2020/04/27 01:51:58 [INFO] Operation Server Listening on 127.0.0.1:9443
2020/04/27 01:51:58 [INFO] generating key: &{A:ecdsa S:256}
2020/04/27 01:51:58 [INFO] encoded CSR
2020/04/27 01:51:58 [INFO] signed certificate with serial number 329534585106560547893187291685042549776140207184
2020/04/27 01:51:58 [INFO] Listening on https://0.0.0.0:7054

我开启了tls,https服务已启动。

好像旧版本需要 运行初始化这个命令。

fabric-ca-server init -b admin:adminpw

得到目录结构

├── ca-cert.pem    CA根证书
├── fabric-ca-server-config.yaml  自动生成的一个配置
├── fabric-ca-server.db      存储CA服务器的用户名,密码。默认用sqllite3,刚刚的admin,adminpw就存在这
├── IssuerPublicKey                    零时证明文件,不知有啥用
├── IssuerRevocationPublicKey      零时证明文件,不知有啥用
├── msp
│   ├── cacerts
│   ├── keystore     这里存放的私钥,暂时没用到。一个是根证书的,有一个应该是tls-cert的。
│   │   ├── 251d980426e6406042f82553d123dd640ac3b63faaba490430eb73b8f023d840_sk
│   │   ├── fabeb56f55f65503c1ec6e91c8163b29607a51d710c5afb65dd62efd93918455_sk
│   │   ├── IssuerRevocationPrivateKey
│   │   └── IssuerSecretKey
│   ├── signcerts
│   └── user
└── tls-cert.pem   tls加密通信根证书。不加--tls.enable不会生成。

sdk代码

主要代码。

 //设置 ca tls根证书,需在ca-server 开启--tls-enable.
        Properties properties = new Properties();
        properties.put("pemBytes", Config.CA_RootCert.getBytes() );

        client = HFCAClient.createNewInstance("https://192.168.128.129:7054", properties);
        client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());

        LocalUser admin = new LocalUser("admin", null);
        Enrollment enrollment = client.enroll("admin", "adminpw");
        System.out.println(enrollment);
        System.out.println(enrollment.getCert());
        System.out.println(enrollment.getKey());
        System.out.println(enrollment.getKey().getFormat());
        System.out.println(enrollment.getKey().getEncoded());
        System.out.println(enrollment.getKey().toString());
        savePemKey(enrollment.getKey());

得到X509格式证书和PKCS#8私钥。

-----BEGIN CERTIFICATE-----
MIIB6zCCAZGgAwIBAgIUfTPoOvyXwqCO3RtQtTeuPaPnobcwCgYIKoZIzj0EAwIw
aDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMt
Y2Etc2VydmVyMB4XDTIwMDQyODAyMDUwMFoXDTIxMDQyODAyMTAwMFowITEPMA0G
A1UECxMGY2xpZW50MQ4wDAYDVQQDEwVhZG1pbjBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABHdnbGw5UYYXdOcXDr9oFEGLSpld2kmshVWWY5Fe9Bvyj+GBuA9WsmzL
N7bNRyFFf644GUWEkUkLRASY07Fw0EyjYDBeMA4GA1UdDwEB/wQEAwIHgDAMBgNV
HRMBAf8EAjAAMB0GA1UdDgQWBBQucA0eiAahGRI5c7ICG9jkjUPWWjAfBgNVHSME
GDAWgBQWJsp41z8dcbDrlotMel4AIKrkuDAKBggqhkjOPQQDAgNIADBFAiEAnpec
IzLvJhIXmJqDtwdS9bPHG7W1mmqwSuZPJFJYqvUCIDP2KSyvK770L+RF5FRvYRFo
Q/8i2HpscmJfeD+Iucb1
-----END CERTIFICATE-----

EC Private Key [2a:4f:55:be:8b:72:8c:5d:48:89:9e:3c:a0:49:4e:98:2d:27:af:ce]
            X: 77676c6c3951861774e7170ebf6814418b4a995dda49ac85559663915ef41bf2
            Y: 8fe181b80f56b26ccb37b6cd4721457fae3819458491490b440498d3b170d04c

将私钥转成常见的格式。

void savePemKey(PrivateKey pk){
        String keyText = "-----BEGIN PRIVATE KEY-----\n" +
                Base64.encode(Unpooled.wrappedBuffer(pk.getEncoded())).toString(CharsetUtil.US_ASCII) +
                "\n-----END PRIVATE KEY-----\n";
        System.out.println(keyText);
    }

得到

-----BEGIN EC PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgefVgGAe4ltBnGxIlflYz6Eeguyob
dj4GAPOaOW0y6g6gCgYIKoZIzj0DAQehRANCAAR3Z2xsOVGGF3TnFw6/aBRBi0qZXdpJrIVVlmOR
XvQb8o/hgbgPVrJsyze2zUchRX+uOBlFhJFJC0QEmNOxcNBM
-----END EC PRIVATE KEY-----

CA注册流程

CA注册分为enroll,和register

  • register 向服务器注册账户,密码。
  • enroll 向服务器申请证书和私钥

fabric-ca是需要管理员进行邀请注册的。 管理员的用户密码就是初始化的时候admin, adminpw,将管理员register到CA服务器。

邀请注册流程

  1. 需知道管理员的用户名,密码还有证书,私钥。若没有,则先用fabric-ca-client enroll得到,或者sdk直接enroll。
  2. 使用管理员作为邀请人,邀请新用户进行register注册。
  3. 新用户注册完成后,用自己的账号密码,向CA服务器enroll证书和私钥。
  • 新注册的用户必须填写ca服务器数据库affiliations表中的组织,里面的字段可以在ca服务器初始化的时候配置。否则注册失败。

用openSSL工具查看信息,校验

参考命令。 openssl查看证书信息 openssl查看公钥私钥信息

将上面的证书和私钥都保存成文件。

#查看私钥
λ openssl.exe pkey -in private -text -noout
Private-Key: (256 bit)
priv:
    79:f5:60:18:07:b8:96:d0:67:1b:12:25:7e:56:33:
    e8:47:a0:bb:2a:1b:76:3e:06:00:f3:9a:39:6d:32:
    ea:0e
pub:
    04:77:67:6c:6c:39:51:86:17:74:e7:17:0e:bf:68:
    14:41:8b:4a:99:5d:da:49:ac:85:55:96:63:91:5e:
    f4:1b:f2:8f:e1:81:b8:0f:56:b2:6c:cb:37:b6:cd:
    47:21:45:7f:ae:38:19:45:84:91:49:0b:44:04:98:
    d3:b1:70:d0:4c
ASN1 OID: prime256v1
NIST CURVE: P-256

查看证书信息。

λ openssl x509 -in cert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            7d:33:e8:3a:fc:97:c2:a0:8e:dd:1b:50:b5:37:ae:3d:a3:e7:a1:b7
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, ST = North Carolina, O = Hyperledger, OU = Fabric, CN = fabric-ca-server
        Validity
            Not Before: Apr 28 02:05:00 2020 GMT
            Not After : Apr 28 02:10:00 2021 GMT
        Subject: OU = client, CN = admin
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:77:67:6c:6c:39:51:86:17:74:e7:17:0e:bf:68:
                    14:41:8b:4a:99:5d:da:49:ac:85:55:96:63:91:5e:
                    f4:1b:f2:8f:e1:81:b8:0f:56:b2:6c:cb:37:b6:cd:
                    47:21:45:7f:ae:38:19:45:84:91:49:0b:44:04:98:
                    d3:b1:70:d0:4c
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                2E:70:0D:1E:88:06:A1:19:12:39:73:B2:02:1B:D8:E4:8D:43:D6:5A
            X509v3 Authority Key Identifier:
                keyid:16:26:CA:78:D7:3F:1D:71:B0:EB:96:8B:4C:7A:5E:00:20:AA:E4:B8

    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:9e:97:9c:23:32:ef:26:12:17:98:9a:83:b7:
         07:52:f5:b3:c7:1b:b5:b5:9a:6a:b0:4a:e6:4f:24:52:58:aa:
         f5:02:20:33:f6:29:2c:af:2b:be:f4:2f:e4:45:e4:54:6f:61:
         11:68:43:ff:22:d8:7a:6c:72:62:5f:78:3f:88:b9:c6:f5

可以看到,在pubkey那一项,是一致的。验证一下。

注意事项

  • fabric-ca-server和fabric网络是独立运行的,admin,adminpw指的是ca服务器的登录用户密码。跟mysql root一个道理。

  • enroll 方法,是向ca服务器申请证书和私钥。 只需要ca服务器的admin账户密码即可。

  • register 向ca服务器注册一个用户,将用户密码写入ca的数据库中。

  • ca服务器的数据库并不保存私钥。

  • 客户端使用的tls证书,用tls-cert.pem或者ca-cert.pem都行。

  • 如果粘贴位字符形式到代码中,务必保留证书的换行符\n或者\r\n,否则报错。

static final String CA_RootCert2 = "-----BEGIN CERTIFICATE-----\n" +
            "MIICYjCCAgmgAwIBAgIUF2bKvlN68EkOyYn3fKW1qDu7HQAwCgYIKoZIzj0EAwIw\n" +
            "aDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK\n" +
            "EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMt\n" +
            "Y2Etc2VydmVyMB4XDTIwMDQyNjA2MzMwMFoXDTIxMDQyNjA2MzMwMFowXDELMAkG\n" +
            "A1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKEwtIeXBl\n" +
            "cmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ0wCwYDVQQDEwRjYTAxMFkwEwYHKoZI\n" +
            "zj0CAQYIKoZIzj0DAQcDQgAEBHtxpXpO6kUgRwng9YiUUYbZhCcE6HqK3wT4cAfH\n" +
            "v40VOKb0sM4julX4eAyQeMaisfmU/fA4Jf2CYPKj0o8sl6OBnDCBmTAOBgNVHQ8B\n" +
            "Af8EBAMCA6gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB\n" +
            "/wQCMAAwHQYDVR0OBBYEFOLKlZOjr1Yo3E3Ac51f9L/ykX6yMB8GA1UdIwQYMBaA\n" +
            "FJjrYMeuageFN72rdUdmWitq7V8FMBoGA1UdEQQTMBGCBGNhMDGCCWxvY2FsaG9z\n" +
            "dDAKBggqhkjOPQQDAgNHADBEAiAOQ6fIprMT0Qq8Mp0HyDA9RLYx2qtqG0qNfkyh\n" +
            "NXpJwgIgdSYiHifAEnl2N9Rj5i8LSkyIgLiQMPV9bksaJONbKcY=\n" +
            "-----END CERTIFICATE-----\n";
  • CSR(证书请求文件) 这个字段的选项需要配置,否则tls会出问题。CSR百度百科

出错

Certificate for <IP> doesn't match any of the subject alternative names:[域名]

跟tls证书的域名和dns有关。 颁发的证书是给制定域名的而非IP地址,因为服务器没有加入Public DNS,所以域名无法访问,我在调用接口时直接使用了IP地址,而不是域名。

需要配置--csr.hosts <自己CA服务器的IP> --crs.hosts 单独这个选项,可以在ca和tls证书中设置IP Address=x.x.x.x --crs.hosts 和 --crs.cn 同时使用, 设置ca证书的CN字段;IP Addresss字段只对CA证书生效,tls证书不生成这两个字段,具体原因不明,这样的话,sdk使用tls链接是,只能使用ca的根证书。

CN(Common Name域名)打算为“chinassl.net”申请SSL证 书,那这个公用名(Common Name)就要填写“chinassl.net”,而不能填写 “www.chinassl.net”,因为在申请SSL证书时发证机构认为“www.yourdomain.com”和 “yourdomain.com”是不同的两个域名 https san自签名证书 CSR字段详解

java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

证书根ca服务器对不上,检查格式,证书等。