1

我正在尝试使用 Hyperledger Fabric Java SDK 来调用链代码事务,但在 channel.initialize() 中出现以下错误:

Exception in thread "main" org.hyperledger.fabric.sdk.exception.TransactionException: org.hyperledger.fabric.sdk.exception.EventHubException: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
    at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:1158)
    at HLFJavaClient.getChannel(HLFJavaClient.java:231)
    at HLFJavaClient.main(HLFJavaClient.java:84)
Caused by: org.hyperledger.fabric.sdk.exception.EventHubException: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
    at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:322)
    at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:200)
    at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:1127)
    ... 2 more
Caused by: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
    at org.hyperledger.fabric.sdk.security.CryptoPrimitives.ecdsaSignToBytes(CryptoPrimitives.java:747)
    at org.hyperledger.fabric.sdk.security.CryptoPrimitives.sign(CryptoPrimitives.java:757)
    at org.hyperledger.fabric.sdk.identity.X509SigningIdentity.sign(X509SigningIdentity.java:23)
    at org.hyperledger.fabric.sdk.transaction.TransactionContext.sign(TransactionContext.java:180)
    at org.hyperledger.fabric.sdk.transaction.TransactionContext.signByteString(TransactionContext.java:184)
    at org.hyperledger.fabric.sdk.EventHub.blockListen(EventHub.java:389)
    at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:320)
    ... 4 more
Caused by: java.security.InvalidKeyException: cannot identify EC private key: java.lang.NullPointerException
    at org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil.generatePrivateKeyParameter(Unknown Source)
    at org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi.engineInitSign(Unknown Source)
    at java.security.Signature$Delegate.engineInitSign(Signature.java:1177)
    at java.security.Signature.initSign(Signature.java:530)
    at org.hyperledger.fabric.sdk.security.CryptoPrimitives.ecdsaSignToBytes(CryptoPrimitives.java:729)
    ... 10 more

我的网络与 4 个对等节点(peer0.org1.mydomain.com、peer0.org2...、peer0.org3... 和 peer0.org4...)和一个排序节点(orderer.mydomain.com)一起运行。

Java SDK 客户端代码:

public class HLFJavaClient {

    public static final String HLF_USER_NAME = "User1@org1.mydomain.com";
    public static final String HLF_CLIENT_ORG = "Org1";
    public static final String HLF_CLIENT_MSPID = "Org1MSP";
    public static final String HLF_CLIENT_CRT_PATH = "../crypto-config/peerOrganizations/org1.mydomain.com/users/User1@org1.mydomain.com/msp/signcerts/User1@org1.mydomain.com-cert.pem";
    public static final String HLF_CLIENT_KEY_PATH = "../crypto-config/peerOrganizations/org1.mydomain.com/users/User1@org1.mydomain.com/msp/keystore/User1@org1.mydomain.com-priv.pem";
    public static final String HLF_CHANNEL_NAME = "mychannel";
    public static final String HLF_CHAINCODE_NAME = "pkicc";

    private static final Logger log = Logger.getLogger(HLFJavaClient.class);


    public static void main(String[] args) throws Exception {


        AppUser appUser = getUser(HLF_CLIENT_CRT_PATH, HLF_CLIENT_KEY_PATH, HLF_USER_NAME);

        HFClient client = getHfClient();

        client.setUserContext(appUser);

        Channel channel = getChannel(client);

        addProperty(client, new String[] {"1","w"});

    }




    static void addProperty(HFClient client, String[] property) throws ProposalException, InvalidArgumentException {
        Channel channel = client.getChannel(HLF_CHANNEL_NAME);
        TransactionProposalRequest tpr = client.newTransactionProposalRequest();
        ChaincodeID CCId = ChaincodeID.newBuilder().setName(HLF_CHAINCODE_NAME).build();
        tpr.setChaincodeID(CCId);
        tpr.setFcn("createWallet");
        tpr.setArgs(property);

        Collection<ProposalResponse> res = channel.sendTransactionProposal(tpr);
        for (ProposalResponse pres : res) {
            String stringResponse = "Response from endorser is: " + pres.getChaincodeActionResponseStatus();
            log.info(stringResponse);
            System.out.println(stringResponse);
        }

        channel.sendTransaction(res);
        System.out.println("Transaction sent.");
    }


    static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {

        Channel channel = client.newChannel(HLF_CHANNEL_NAME);

        class PeerOrgPort {
            public String org;
            public int port;

            public PeerOrgPort(String org, int port) {
                this.org = org;
                this.port = port;
            }
        }

        PeerOrgPort[] peers = new PeerOrgPort[] {
                new PeerOrgPort("1", 7051),
                new PeerOrgPort("2", 8051),
                new PeerOrgPort("3", 9051),
                new PeerOrgPort("4", 10051),
        };


        for (int i = 0; i < peers.length; i++) {
            File tlsCrt = Paths.get("../crypto-config/peerOrganizations/org" + peers[i].org + ".mydomain.com/tlsca", "tlsca.org" + peers[i].org + ".mydomain.com-cert.pem").toFile();

            if (!tlsCrt.exists())
                throw new RuntimeException("Missing TLS cert files");

            Properties secPeerProperties = new Properties();
            secPeerProperties.setProperty("hostnameOverride", "peer0.org" + peers[i].org + ".mydomain.com");
            secPeerProperties.setProperty("sslProvider", "openSSL");
            secPeerProperties.setProperty("negotiationType", "TLS");
            secPeerProperties.setProperty("pemFile", tlsCrt.getAbsolutePath());

            Peer peer = client.newPeer("peer0.org" + peers[i].org + ".mydomain.com", "grpcs://localhost:"  + peers[i].port, secPeerProperties);
            channel.addPeer(peer);


            if (peers[i].org.equals("1")) {
                EventHub eventHub = client.newEventHub("eventhub01", "grpcs://localhost:7053", secPeerProperties);
                channel.addEventHub(eventHub);
            }
        }


        File tlsOrdCrt = Paths.get("../crypto-config/ordererOrganizations/mydomain.com/tlsca", "tlsca.mydomain.com-cert.pem").toFile();
        if (!tlsOrdCrt.exists())
            throw new RuntimeException("Missing TLS cert files");

        Properties secOrdererProperties = new Properties();
        secOrdererProperties.setProperty("hostnameOverride", "orderer.mydomain.com");
        secOrdererProperties.setProperty("sslProvider", "openSSL");
        secOrdererProperties.setProperty("negotiationType", "TLS");
        secOrdererProperties.setProperty("pemFile", tlsOrdCrt.getAbsolutePath());

        Orderer orderer = client.newOrderer("orderer.mydomain.com", "grpcs://localhost:7050", secOrdererProperties);

        channel.addOrderer(orderer);
        channel.initialize();

        return channel;
    }

    static HFClient getHfClient() throws Exception {
        CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
        HFClient client = HFClient.createNewInstance();
        client.setCryptoSuite(cryptoSuite);
        return client;
    }

    static AppUser getUser(String certPath, String keyPath, String userId) throws Exception {
        AppUser appUser = null;//tryDeserialize(userId);
        if (appUser == null) {
            appUser = new AppUser(userId, HLF_CLIENT_ORG, HLF_CLIENT_MSPID, certPath, keyPath);
        }
        return appUser;
    }

应用用户:

public class AppUser implements User, Serializable {

    private static final long serializationId = 1L;
    private static final long serialVersionUID = -6287264119837208213L;

    private String name;
    private Set<String> roles;
    private String account;
    private String affiliation;
    private Enrollment enrollment;
    private String mspId;

    public AppUser() {
        // no-arg constructor
    }

    public AppUser(String name, String affiliation, String mspId, String certPath, String keyPath) {
        this.name = name;
        this.affiliation = affiliation;
        this.enrollment = getEnrollmentFromCertPath(certPath, keyPath);
        this.mspId = mspId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<String> getRoles() {
        return roles;
    }

    public void setRoles(Set<String> roles) {
        this.roles = roles;
    }


    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }


    public String getAffiliation() {
        return affiliation;
    }

    public void setAffiliation(String affiliation) {
        this.affiliation = affiliation;
    }


    public Enrollment getEnrollment() {
        return enrollment;
    }

    public void setEnrollment(Enrollment enrollment) {
        this.enrollment = enrollment;
    }


    public String getMspId() {
        return mspId;
    }

    public void setMspId(String mspId) {
        this.mspId = mspId;
    }

    @Override
    public String toString() {
        return "AppUser{" +
                "name='" + name + '\'' +
                "\n, roles=" + roles +
                "\n, account='" + account + '\'' +
                "\n, affiliation='" + affiliation + '\'' +
                "\n, enrollment=" + enrollment +
                "\n, mspId='" + mspId + '\'' +
                '}';
    }

    private Enrollment getEnrollmentFromCertPath(final String certPath, final String keyPath) {
        return new Enrollment() {


            public PrivateKey getKey() {
                try {
                    return loadPrivateKey(Paths.get(keyPath));
                } catch (Exception e) {
                    return null;
                }
            }


            public String getCert() {
                try {
                    return new String(Files.readAllBytes(Paths.get(certPath)));
                } catch (Exception e) {
                    return "";
                }
            }

        };
    }

    private static PrivateKey loadPrivateKey(Path fileName) throws IOException, GeneralSecurityException {
        PrivateKey key = null;
        InputStream is = null;
        BufferedReader br  = null;
        try {
            is = new FileInputStream(fileName.toString());
            br = new BufferedReader(new InputStreamReader(is));
            StringBuilder builder = new StringBuilder();
            boolean inKey = false;
            for (String line = br.readLine(); line != null; line = br.readLine()) {
                if (!inKey) {
                    if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) {
                        inKey = true;
                    }
                    continue;
                } else {
                    if (line.startsWith("-----END ") && line.endsWith(" PRIVATE KEY-----")) {
                        inKey = false;
                        break;
                    }
                    builder.append(line);
                }
            }
            byte[] encoded = DatatypeConverter.parseBase64Binary(builder.toString());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
            KeyFactory kf = KeyFactory.getInstance("ECDSA", "BC");
            key = kf.generatePrivate(keySpec);
        } finally {
            br.close();
            is.close();
        }
        return key;
    }
}

我究竟做错了什么?

谢谢

4

0 回答 0