Node.js Hyperledger结构:无法更新节点SDK中的证书属性

Node.js Hyperledger结构:无法更新节点SDK中的证书属性,node.js,hyperledger-fabric,blockchain,x509certificate,Node.js,Hyperledger Fabric,Blockchain,X509certificate,我正在制作一个区块链应用程序,我正在为其使用Hyperledger Fabric Node SDK。当用户注册时,用户的证书将作为身份添加到钱包中。现在,我存储在用户证书中的属性是电子邮件和密码。 此外,用户的密码不会存储在其他任何地方,而只存储在证书中。 现在,我还需要更新用户的密码 通过在internet上搜索,我知道可以使用节点中提供的identityService更新功能更新证书中的属性,如果使用identityService更新功能,则无需重新注册用户。 问题是我试过了,结果显示密码更

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

通过在internet上搜索,我知道可以使用节点中提供的identityService更新功能更新证书中的属性,如果使用identityService更新功能,则无需重新注册用户。 问题是我试过了,结果显示密码更新了。 但是当我检查证书时,旧密码仍然在那里,也就是说,它没有被更新。 对于FabricCAServices,我使用的是fabric ca client包,对于x509证书,我使用的是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证书中的属性,或者是否正在重新滚动此所需的用户?

您可以按照您所说的执行
重新滚动
来修复它

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


为什么attr更改需要新证书

  • Fabric通常使用X.509证书标准方法。(不使用idemix时)
  • 实际上,不仅是Fabric,web上几乎所有的证书都遵循该标准
  • 在Fabric中,
    Attr
    存在于X509(v3)证书的
    扩展中,并具有以下格式
X509v3扩展:
...
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)中,
    扩展也包括在证书完整性验证过程中
  • 完整性验证过程基于
    PKI
    Hash
    实现,并以将CA签名的
    签名
    附加到证书的哈希数据(包括扩展)的形式提供
  • 也就是说,如果修改了
    扩展名
    ,则必须修改证书中的
    签名
    ,这意味着必须颁发新证书

回到织物方面

  • reenroll
    命令是基于
    注册用户
    新发布
注册用户数据的行为
  • 更新后
    ,通过
    重新滚动
    命令颁发新证书,以获得相应证书中包含
    新属性的证书
  • 下面的示例代码已经过测试,可以正常工作。看这个

    //registerUser、enrollUser、updateUser、reEnrollUser
    /*
    *版权归IBM公司所有。保留所有权利。
    *
    *SPDX许可证标识符:Apache-2.0
    */
    "严格使用",;
    const{Wallets}=require('fabric-network');
    const FabricCAServices=require('fabric-ca-client');
    常数fs=要求('fs');
    const path=require('path');
    异步函数main(){
    试一试{
    //0.给定,已注册为“管理员”
    const ccpPath=path.resolve(uu dirname,“…”,“…”,“测试网络”,“组织”,“对等组织”,“org1.example.com”,“connection-org1.json”);
    const ccp=JSON.parse(fs.readFileSync(ccpath,'utf8');
    const caURL=ccp.certificateAuthorities['ca.org1.example.com'].url;
    const ca=新的制造服务(caURL);
    const walletPath=path.join(process.cwd(),“wallet”);
    const wallet=wait wallet.newFileSystemWallet(walletPath);
    const provider=wallet.getProviderRegistry().getProvider('X.509');
    //1.注册testUser
    const adminIdentity=wait wallet.get('admin');
    const appUser='testUser';
    const adminUser=wait provider.getUserContext(adminIdentity,'admin');
    const secret=等待ca寄存器({
    隶属关系:'org1.部门2',
    属性:[{name:'userType',value:'userType',ecert:true}],
    注册ID:appUser,
    角色:“客户”
    },adminUser);
    //2.注册testUser
    常量注册=等待ca注册({
    注册ID:appUser,
    注册秘密:秘密
    });
    常数x509Identity={
    证书:{
    证书:注册。证书,
    privateKey:enrollment.key.toBytes(),
    },
    mspId:'Org1MSP',
    类型:“X.509”,
    };
    等待钱包。放置(appUser,x509Identity);
    //3.在Fabric CA中更新testUser的身份
    const-appUserIdentity=wait wallet.get(appUser);
    const newAppUser=wait provider.getUserContext(appUserIdentity,appUser);
    const identityService=ca.newIdentity
    
    // 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"}}