在Hyperledger Fabric中为用户身份设置PEM属性

Mru*_*kla 2 hyperledger-fabric hyperledger-fabric-ca hyperledger-fabric-sdk-js

我有一个带有一个Fabric CA的单组织设置。CA Server与MySQL一起运行。我正在使用NodeSDK来连接事务并将其发布到Chaincode。

我能够为同行和订购者设置国家,州,地区,组织和组织单位属性。但是,当我在Fabric中注册并注册“用户”时,并不是所有属性都已设置。从证书文件中可以看到,仅设置了“公用名”和“组织单位”属性。

以下是我用于注册和注册用户的代码段:

await gateway.connect(connectionProfile, { wallet, identity: 'admin', discovery: { enabled: false } });

ca = await gateway.getClient().getCertificateAuthority();
adminIdentity = gateway.getCurrentIdentity();

const secret = await ca.register({
                affiliation: user.$affiliation,
                enrollmentID: user.$name,
                role: user.$role,
               }, adminIdentity);

const enrollment = await ca.enroll({
                    enrollmentID: user.$name,
                    enrollmentSecret: secret,
                 });
const userIdentity = await X509WalletMixin.createIdentity(process.env.ACTIVE_MSP, enrollment.certificate, enrollment.key.toBytes());
Run Code Online (Sandbox Code Playgroud)

在这里,“用户”是我在应用程序中使用的参与者的模型。公用名(CN)设置为“ enrollmentID”,组织单位设置为“ role” +“ affiliation”,并且为用户生成的证书具有以下信息:

Owner: CN=jondoe, OU=client + OU=admin.forwarder.com
Issuer: CN=ca.allparticipants.logistics.com, 
O=allparticipants.logistics.com, L=Bengaluru, ST=Karnataka, C=IN
Serial number: ea385863390c07c320fd6717de7878fd9f81dc3e
Valid from: Mon Apr 15 14:11:00 IST 2019 until: Tue Apr 14 14:16:00 IST 2020
Certificate fingerprints:
     MD5:  …<value>
     SHA1: …<value>
     SHA256: …<value>
Signature algorithm name: SHA256withECDSA
Subject Public Key Algorithm: 256-bit EC key
Version: 3

Extensions: 
…
Run Code Online (Sandbox Code Playgroud)

如我们所见,颁发者的完整C,ST,L,O,OU和CN属性可用。这属于相应组织的MSP。但是,仅用户的CN和OU可用。

因此,有一种方法可以在注册或注册用户时设置用户的其他属性(C,ST,L和O)。还是我们必须从发行者信息中推断出这些属性?

更新:1:我检查了node-sdk内部调用的fabric-ca-client cli选项。检查了注册api。它也没有设置C,ST,L和O的选项。

更新:fabric-ca是否支持将这些属性设置为“使用者名称”?

更新:2:遍历fabric-ca-client的文档并按照@nyet的建议,我观察到我们可以在csr.names属性中设置这些值,并将其提供给enroll命令的'csr'参数。以下是更新的代码段:

await gateway.connect(connectionProfile, { wallet, identity: 'admin', discovery: { enabled: false } });

ca = await gateway.getClient().getCertificateAuthority();
Run Code Online (Sandbox Code Playgroud)

adminIdentity = gateway.getCurrentIdentity();

const secret = await ca.register({
            affiliation: user.$affiliation,
            enrollmentID: user.$name,
            role: user.$role,
           }, adminIdentity);

const csrObj: any = {};
csrObj.names = 'O=Forwarder,C=IN,ST=Karnataka,L=Bengaluru';

const enrollment = await ca.enroll({
            csr: csrObj.toString(),
            enrollmentID: user.$name,
            enrollmentSecret: secret,
            });

const userIdentity = await X509WalletMixin.createIdentity(process.env.ACTIVE_MSP, enrollment.certificate, enrollment.key.toBytes());
Run Code Online (Sandbox Code Playgroud)

但是,我得到一个错误,说:

无法注册smithdoe20,错误:%o message =注册失败,错误为[[{{“ code”:0,“ message”:“ {\” code \“:9002,\” message \“:\” CSR解码失败\ “}”}]]],堆栈=错误:注册失败,并显示错误[[{{code“:0,” message“:” {\“ code \”:9002,\“ message \”:\“ CSR解码失败\ “}”}]]

类似的JIRA问题:https : //jira.hyperledger.org/browse/FAB-14051? jql = project%20%3D%20FAB%20AND%20statusCategory%20!%3D%20Done%20AND%20type%20%3D%20Bug %20AND%20component%20%3D%20fabric-sdk-node%20AND%20project%20%3D%20FAB%20ORDER%20BY%20createdDate%20ASC

更新:3:Node-SDK文档指出CSR字段应为PEM编码的PKCS#10证书签名请求。

  1. 我尝试利用node-forge npm模块生成密钥并使用它签名建议。但是,这提供了RSA密钥。
  2. 尝试使用node-pem。也没有解决。

最后,尝试使用以下命令生成ECDSA密钥并离线创建CSR:1.密钥生成:openssl ecparam -name prime256v1 -genkey -noout -out my-key.pem 2. CSR:openssl req -new -sha256 -key my-key.pem -out my.csr

从文件系统中读取此CSR,并将其传递给“注册请求”,如下所示:

 const csrNewVal = readFileSync('/Users/mrudavshukla/projects/pem-trials/ecdsa/my.csr', 'utf8');
 const enrollment = await ca.enroll({
                    csr: csrNewVal,
                    enrollmentID: user.$name,
                    enrollmentSecret: secret,
                });
Run Code Online (Sandbox Code Playgroud)

能够成功注册用户。

现在,当我们通过CSR时,fabric-ca不会将注册密钥返回给我们。因此,我从文件系统中的#1命令中检索了私钥,并尝试按如下方式将该用户的身份详细信息保存在X509钱包中:

const privateNewVal = readFileSync('/Users/mrudavshukla/projects/pem-trials/ecdsa/my-key.pem', 'utf8');
const userIdentity = await X509WalletMixin.createIdentity(process.env.ACTIVE_MSP, enrollment.certificate, privateNewVal);
Run Code Online (Sandbox Code Playgroud)

但是,这将引发以下错误:

错误:[crypto_ecdsa_aes]:importKey-{“ message”:“不了解ECDSA私钥和证书以外的PEM内容”,“堆栈”:“错误:不了解ECDSA私钥和证书以外的PEM内容... 。

接下来,我尝试使用fabric-ca在不提供CSR时生成的证书检查为该用户保存的证书。两者在结构和用于公钥的签名算法方面都完全相同。

我是否错过任何关键部分?

Mru*_*kla 5

没有必要寻找其他模块来生成ECDSA密钥并使用这些密钥对CSR进行签名。架构本身提供了执行此操作的模块。解决方法如下:

  1. “ fabric-client”模块提供CryptoSuite实现。使用此加密套件,我们可以生成密钥。这些密钥将是ECDSA 256位密钥。
  2. 我们可以使用“ jsrsasign”模块来创建CSR。在创建CSR时,我们可以将#1中生成的密钥与主题信息一起传递给该方法。它的实现将对其进行签名。当我们不通过CSR时,Fabric内部使用此方法。
  3. 接下来,将此CSR传递给EnrollmentRequest。
  4. 在使用X509WalletMixin创建要存储到钱包中的身份时,请使用注册请求中的证书和从#1生成的密钥。

代码如下:

await gateway.connect(connectionProfile, { wallet, identity: 'admin', discovery: { enabled: false } });

ca = await gateway.getClient().getCertificateAuthority();
adminIdentity = gateway.getCurrentIdentity();

const secret = await ca.register({
                affiliation: user.$virtualOrganizationBranch,
                enrollmentID: user.$name,
                role: user.$role,
            }, adminIdentity);

const privateKey = await hfc.newCryptoSuite().generateKey({ephemeral: true});

const subjectDN: string = 'CN=' + user.$name + ',C=IN,ST=Karnataka,L=Bengaluru,O=Forwarder';

const asn1 = jsrsa.asn1;
const csr = asn1.csr.CSRUtil.newCSRPEM({
                sbjprvkey: privateKey.toBytes(),
                sbjpubkey: privateKey.getPublicKey().toBytes(),
                sigalg: 'SHA256withECDSA',
                subject: {str: asn1.x509.X500Name.ldapToOneline(subjectDN)},
            });

const enrollment = await ca.enroll({
                csr,
                enrollmentID: user.$name,
                enrollmentSecret: secret,
            });

const userIdentity = await X509WalletMixin.createIdentity(process.env.ACTIVE_MSP, enrollment.certificate, privateKey.toBytes());
await wallet.import(user.$name, userIdentity);
Run Code Online (Sandbox Code Playgroud)