我有一个使用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());
这里,“user”是我在我的应用程序中使用的参与者的模型。公共名称(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:
…
我们可以看到,发行人的完整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();
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());
但是,我得到一个错误,说:
无法注册smithdoe20,错误:%o message =注册失败,错误[[{“code”:0,“message”:“{\”code \“:9002,\”message \“:\”CSR解码失败\ “}”}]],stack =错误:注册失败并出现错误[[{“code”:0,“message”:“{\”code \“:9002,\”message \“:\”CSR解码失败\ “}”}]]
更新:3:Node-SDK文档指出CSR字段应该是PEM编码的PKCS#10证书签名请求。
最后,尝试使用以下命令生成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,
});
能够成功注册用户。
现在,当我们通过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);
但是,这会引发以下错误:
错误:[crypto_ecdsa_aes]:importKey - {“message”:“不理解除ECDSA私钥和证书之外的PEM内容”,“堆栈”:“错误:不了解除ECDSA私钥和证书之外的PEM内容... 。
接下来,我尝试使用fabric-ca在我们不提供CSR时生成的证书来检查为此用户保存的证书。两者在结构和用于公钥的签名算法上完全相同。
我错过了任何关键部分吗?
没有必要寻找其他模块来生成ECDSA密钥并使用这些密钥签署CSR。结构本身提供了这样做的模块。解决方法步骤:
代码如下:
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);
如果使用fabric-ca-client
,fabric-ca-client enroll --csr.names "O=Org,C=US,ST=State,L=Locality" ...
应该可以使用。我知道这不是节点,但希望它能让你朝着正确的方向前进。