繁体   English   中英

Hyperledger Fabric:无法更新节点 SDK 中的证书属性

[英]Hyperledger Fabric: Unable to Update Certificate Attributes in Node SDK

我正在制作一个使用Hyperledger Fabric Node SDK的区块链应用程序。 当用户注册时,用户的证书将作为身份添加到钱包中。 现在我存储在用户证书中的属性是email 和 password 此外,用户的密码不会存储在其他任何地方,而只会存储在证书中。 现在,我还需要更新用户的密码。

在互联网上搜索,我知道证书中的属性可以使用 Node 中提供的identityService 的更新 function进行更新,如果您使用的是 identityService 的更新 function,则无需重新注册用户。 问题是我试过了,响应显示更新的密码。 但是当我检查证书时,旧密码仍然存在,即尚未更新。 我将fabric-ca-client package 用于 FabricCAServices,将x509 package 用于 x509 证书。

我注册和注册用户的代码如下:

let ccp = await getCCP(orgName);
const caURL = await getCaUrl(orgName, ccp)
const ca = new FabricCAServices(caURL);
    
const walletPath = await getWalletPath(orgName);
const wallet = await Wallets.newFileSystemWallet(walletPath);
logger.info(`Wallet path: ${walletPath}`);

const userIdentity = await wallet.get(email); //getting user from the wallet
if (userIdentity) //if found so user is already registered
{
    return "User Already Exists";
}
    
//else user does not exist so checking if admin exists
let adminIdentity = await wallet.get('admin'); //getting admin from wallet
if (!adminIdentity) { //if not found so admin does not exist
    logger.debug('An identity for the admin user "admin" does not exist in the wallet');
    await enrollAdmin(orgName, ccp); //enrolling the admin
    adminIdentity = await wallet.get('admin');
    logger.debug("Admin Enrolled Successfully");
}

//now admin exists, so making a user object for authenticating with the CA(i.e. admin)
const provider = wallet.getProviderRegistry().getProvider(adminIdentity.type);
const adminUser = await provider.getUserContext(adminIdentity, 'admin');
let secret;
try {
    //registering the user, enrolling the user, and importing the new identity into the wallet.
    secret = await ca.register({ affiliation: 'org1.department1', enrollmentID: email, role: 'client', attrs: [{name: 'userType', value: userType, ecert: true},{name: 'password', value: password, ecert: true}]}, adminUser);
} catch (error) {
    return error.message;
}

const enrollment = await ca.enroll({ enrollmentID: email, enrollmentSecret: secret, attr_reqs: [{  name: 'userType', optional: false }, {  name: 'password', optional: false }] });

let x509Identity;
if (orgName == "Org1") {
    x509Identity = {
        credentials: {
            certificate: enrollment.certificate,
            privateKey: enrollment.key.toBytes(),
        },
        mspId: 'Org1MSP',
        type: 'X.509',
    };
} else if (orgName == "Org2") {
    x509Identity = {
        credentials: {
            certificate: enrollment.certificate,
            privateKey: enrollment.key.toBytes(),
        },
        mspId: 'Org2MSP',
        type: 'X.509',
    };
}
await wallet.put(email, x509Identity); //adding user to wallet
return "Registered!";

我检查存储在密码中的属性的代码是:

//Getting wallet path for orgName...
const walletPath = await getWalletPath(orgName);
const wallet = await Wallets.newFileSystemWallet(walletPath);
logger.info(`Wallet path: ${walletPath}`);

//getting this user from the wallet
const userIdentity = await wallet.get(email);
if (userIdentity) { //if found i.e. user is registered
    //parsing certificate to get password
    var issuer = x509.parseCert(userIdentity.credentials.certificate);
    var jsn = issuer.extensions['1.2.3.4.5.6.7.8.1'];
    jsn = jsn.substring(2);
    jsn = (JSON.parse(jsn));
    //here jsn.attrs.password has the password
}

我用来更新证书属性的代码是:

let ccp = await getCCP(orgName);
const caURL = await getCaUrl(orgName, ccp);
const ca = new FabricCAServices(caURL);

//Getting wallet path for orgName...
const walletPath = await getWalletPath(orgName);
const wallet = await Wallets.newFileSystemWallet(walletPath);
logger.info(`Wallet path: ${walletPath}`);

const userIdentity = await wallet.get(email); //getting this user from the wallet
if (userIdentity) { //if found i.e. user is registered

    //Create a new gateway for connecting to our peer node
    const gateway = new Gateway();
    await gateway.connect(ccp, { wallet, identity: email, discovery: { enabled: true, asLocalhost: true } });

    const identityService = ca.newIdentityService();

    let adminIdentity = await wallet.get('admin'); //getting admin from wallet
    //now making a user object of the admin
    const provider = wallet.getProviderRegistry().getProvider(adminIdentity.type);
    const adminUser = await provider.getUserContext(adminIdentity, 'admin');

    var theIdentityRequest = { enrollmentID: email, affiliation: 'org1.department1', attrs: [ {name: 'userType', value: 'Student', ecert: true},{name: 'password', value: newPassword, ecert: true} ] };

    logger.warn("The Request: ", theIdentityRequest);

    let response = await identityService.update(email, theIdentityRequest, adminUser);
                
    logger.warn("userIdenity attributes: ",response.result.attrs);

    await gateway.disconnect();
}

我想知道为什么证书仍然有旧密码以及如何更新证书中的密码。 而且我还想知道 identityService 是否更新了 x509 证书中的属性,还是为此重新注册了必要的用户?

您可以按照您所说的reenroll来修复它。

IdentityServiceupdate命令是更新 CA 中registered用户的身份。
由于这不是更新证书的过程,因此获取包含新修改的Attr的证书的唯一方法是获取新证书(该证书是 X.509 标准)。


为什么 attr 更改需要新证书?

  • Fabric一般使用X.509证书标准方法。(不使用idemix时)
  • 其实不只是Fabric,几乎所有web上的证书都遵循标准。
  • 在 Fabric 中, Attr存在于 X509(v3) 证书的extensions中,格式如下。
X509v3 extensions:
    ...
    1.2.3.4.5.6.7.8.1:
        {"attrs":{"hf.Affiliation":"org1.department1","hf.EnrollmentID":"appUser5","hf.Type":"client","userType":"userType"}}
    ...
  • 换句话说,当Attr被修改时, extensions被修改。
  • 在 X.509(v3) 中, extenstions也包含在证书完整性验证过程中。
  • 完整性验证过程基于PKIHash实现,并以 CA 签署的signature附加到证书的散列数据(包括扩展)的形式提供。
  • 即如果修改了extensions ,则必须修改证书中的signature ,这意味着必须颁发新的证书

回到面料,

  • reenroll命令是基于registered user newly issuing注册用户数据的行为。
  • updating后,通过reenroll命令颁发新证书,获取对应证书中包含new Attrs的证书。

以下示例代码已经过测试并且可以工作。 看到这个。

// registerUser, enrollUser, updateUser, reEnrollUser

/*
 * Copyright IBM Corp. All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

'use strict';

const { Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client');
const fs = require('fs');
const path = require('path');

async function main() {
    try {
        // 0. given, already enrolled 'admin'
        const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
        const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
        const caURL = ccp.certificateAuthorities['ca.org1.example.com'].url;
        const ca = new FabricCAServices(caURL);
        const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        const provider = wallet.getProviderRegistry().getProvider('X.509');
        
        // 1. register testUser
        const adminIdentity = await wallet.get('admin');
        const appUser = 'testUser';
        const adminUser = await provider.getUserContext(adminIdentity, 'admin');
        const secret = await ca.register({
                affiliation: 'org1.department2',
                attrs: [{name: 'userType', value: 'userType', ecert: true}],
                enrollmentID: appUser,
                role: 'client'
        }, adminUser);

        // 2. enroll testUser
        const enrollment = await ca.enroll({
                enrollmentID: appUser,
                enrollmentSecret: secret
        });
        const x509Identity = {
                credentials: {
                        certificate: enrollment.certificate,
                        privateKey: enrollment.key.toBytes(),
                },
                mspId: 'Org1MSP',
                type: 'X.509',
        };
        await wallet.put(appUser, x509Identity);

        // 3. update testUser's Identity in Fabric-CA
        const appUserIdentity = await wallet.get(appUser);
        const newAppUser = await provider.getUserContext(appUserIdentity, appUser);
        const identityService = ca.newIdentityService();
        var theIdentityRequest = { enrollmentID: appUser, affiliation: 'org1.department1', attrs: [ {name: 'userType', value: 'Student', ecert: true} ] };
        let response = await identityService.update(appUser, theIdentityRequest, adminUser);
        console.log("userIdenity attributes: ", response.result.attrs);

        // 4. reenroll testUser
        const newEnrollment = await ca.reenroll(newAppUser);
        const newX509Identity = {
                credentials: {
                        certificate: newEnrollment.certificate,
                        privateKey: newEnrollment.key.toBytes(),
                },
                mspId: 'Org1MSP',
                type: 'X.509',
        };
        await wallet.put(`new_${appUser}`, newX509Identity);

    } catch (error) {
        console.error(`Failed to register user "appUser": ${error}`);
        process.exit(1);
    }
}
ls wallet
testUser.id  new_testUser.id

docode 颁发证书的结果(更新hf.AffiliationuserType

// attrs in 'enroll' Certificate's extensions
{"attrs": "hf.Affiliation":"org1.department2","hf.EnrollmentID":"testUser","hf.Type":"client","userType":"userType"}}

// attrs in 'reenroll' Certificate's extensions
{"attrs":{"hf.Affiliation":"org1.department1","hf.EnrollmentID":"testUser","hf.Type":"client","userType":"Student"}}

[PS] 看客户身份标明的Version ,好像有办法升级现有的,但我没有检查或尝试过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM