Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 锯齿形无效批次或签名_Java_Blockchain_Hyperledger_Java Security_Hyperledger Sawtooth - Fatal编程技术网

Java 锯齿形无效批次或签名

Java 锯齿形无效批次或签名,java,blockchain,hyperledger,java-security,hyperledger-sawtooth,Java,Blockchain,Hyperledger,Java Security,Hyperledger Sawtooth,我最近开始使用Hyperledger Sawtooth玩atound,在java上提交事务时遇到了麻烦,而python代码似乎还可以 我已经基于编写了python代码,然后尝试用java编写了一个。下面是java中的代码 import com.google.protobuf.ByteString; import com.mashape.unirest.http.Unirest; import sawtooth.sdk.processor.Utils; import sawtooth.sdk.pr

我最近开始使用Hyperledger Sawtooth玩atound,在java上提交事务时遇到了麻烦,而python代码似乎还可以

我已经基于编写了python代码,然后尝试用java编写了一个。下面是java中的代码

import com.google.protobuf.ByteString;
import com.mashape.unirest.http.Unirest;
import sawtooth.sdk.processor.Utils;
import sawtooth.sdk.protobuf.*;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;

public class BatchSender {

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


        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec parameterSpec = new ECGenParameterSpec("secp256k1");

        keyPairGenerator.initialize(parameterSpec);

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");

        ecdsaSign.initSign(keyPair.getPrivate());


        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        String publicKeyHex = Utils.hash512(publicKeyBytes);

        ByteString publicKeyByteString = ByteString.copyFrom(new String(publicKeyBytes),"UTF-8");


        String payload = "{'key':1, 'value':'value comes here'}";
        String payloadBytes = Utils.hash512(payload.getBytes());

        ByteString payloadByteString  = ByteString.copyFrom(payload.getBytes());


        TransactionHeader txnHeader = TransactionHeader.newBuilder().
                setBatcherPubkeyBytes(publicKeyByteString).
                setFamilyName("plain_info").
                setFamilyVersion("1.0").
                addInputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setNonce("1").
                addOutputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7").
                setPayloadEncoding("application/json").
                setPayloadSha512(payloadBytes).
                setSignerPubkey(publicKeyHex).build();


        ByteString txnHeaderBytes = txnHeader.toByteString();
        ecdsaSign.update(txnHeaderBytes.toByteArray());
        byte[] txnHeaderSignature = ecdsaSign.sign();



        Transaction txn = Transaction.newBuilder().setHeader(txnHeaderBytes).setPayload(payloadByteString).setHeaderSignature(Utils.hash512(txnHeaderSignature)).build();

        BatchHeader batchHeader = BatchHeader.newBuilder().setSignerPubkey(publicKeyHex).addTransactionIds(txn.getHeaderSignature()).build();

        ByteString batchHeaderBytes = batchHeader.toByteString();



        ecdsaSign.update(batchHeaderBytes.toByteArray());

        byte[] batchHeaderSignature = ecdsaSign.sign();

        Batch batch = Batch.newBuilder().setHeader(batchHeaderBytes).setHeaderSignature(Utils.hash512(batchHeaderSignature)).addTransactions(txn).build();


        BatchList batchList = BatchList.newBuilder().addBatches( batch).build();


        ByteString batchBytes = batchList.toByteString();


        String serverResponse =  Unirest.post("http://rest-api:8080/batches").header("Content-Type","application/octet-stream").body(batchBytes.toByteArray()).asString().getBody();

        System.out.println(serverResponse);
    }


}
一旦我运行它,我就会

{
  "error": {
    "code": 30,
    "message": "The submitted BatchList was rejected by the validator. It was poorly formed, or has an invalid signature.",
    "title": "Submitted Batches Invalid"
  }
}
在dockers日志上,我可以看到

sawtooth-validator-default | [2017-11-21 08:20:09.842 DEBUG    interconnect] ServerThread receiving CLIENT_BATCH_SUBMIT_REQUEST message: 1242 bytes
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    signature_verifier] batch failed signature validation: 30a2f4a24be3e624f5a35b17cb505b65cb8dd41600545c6dcfac7534205091552e171082922d4eb71f1bb186fe49163f349c604b631f64fa8f1cfea1c8bb2818
sawtooth-validator-default | [2017-11-21 08:20:09.844 DEBUG    interconnect] ServerThread sending CLIENT_BATCH_SUBMIT_RESPONSE to b'50b094689ac14b39'
我已经检查了密钥大小并验证了签名,看起来一切正常,但是,我找不到该批被拒绝的原因


以前有人对sawtooth有类似的错误反应吗?上述代码是批处理格式还是仍然存在签名问题?

问题在于设置批头签名和事务头签名。那些不应该有sha-512散列。这些字节应编码为十六进制字符串

使用apache commons编解码器库,可以执行以下操作:

import org.apache.commons.codec.binary.Hex;

Transaction txn = Transaction.newBuilder()
                      .setHeader(txnHeaderBytes)
                      .setPayload(payloadByteString)
                      .setHeaderSignature(Hex.encodeHexString(txnHeaderSignature))
                    .build();

Utils.sha512应仅用于有效负载字节。

锯齿Java SDK附带了一个
签名
类,可用于 生成私钥/公钥对和签名消息

我已经修改了您的代码以使用指定的类,并包含了对工作示例的更改(这是使用Sawtooth Java SDK版本1.0):


我也有同样的问题。在我的例子中,问题在于设置有效负载数据

确保:
  • 您对PayloadByteArray进行了sha512哈希,并将其传递给TransactionHeader创建
  • 将PayloadByteArray传递给事务创建
因此:
  • PayloadByteArray->事务创建
  • sha512 PayloadByteArray的哈希->事务标头创建

这个问题已经解决了吗?如果是这样的话,解决办法是什么?@FrankC。不,没有解决。你有没有想过在iOS上做同样的事情?你有什么答案吗?你有没有想过在iOS上做同样的事情?
import com.google.protobuf.ByteString;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.bitcoinj.core.ECKey;
import sawtooth.sdk.client.Signing;
import sawtooth.sdk.processor.Utils;
import sawtooth.sdk.protobuf.Batch;
import sawtooth.sdk.protobuf.BatchHeader;
import sawtooth.sdk.protobuf.BatchList;
import sawtooth.sdk.protobuf.Transaction;
import sawtooth.sdk.protobuf.TransactionHeader;

import java.security.SecureRandom;

public class BatchSender {

  public static void main(String []args) throws UnirestException {
    ECKey privateKey = Signing.generatePrivateKey(new SecureRandom());
    String publicKey = Signing.getPublicKey(privateKey);

    ByteString publicKeyByteString = ByteString.copyFromUtf8(publicKey);

    String payload = "{'key':1, 'value':'value comes here'}";
    String payloadBytes = Utils.hash512(payload.getBytes());
    ByteString payloadByteString  = ByteString.copyFrom(payload.getBytes());

    TransactionHeader txnHeader = TransactionHeader.newBuilder()
            .setBatcherPublicKeyBytes(publicKeyByteString)
            .setSignerPublicKeyBytes(publicKeyByteString)
            .setFamilyName("plain_info")
            .setFamilyVersion("1.0")
            .addInputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
            .setNonce("1")
            .addOutputs("1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
            .setPayloadSha512(payloadBytes)
            .setSignerPublicKey(publicKey)
            .build();
    ByteString txnHeaderBytes = txnHeader.toByteString();
    String txnHeaderSignature = Signing.sign(privateKey, txnHeaderBytes.toByteArray());

    Transaction txn = Transaction.newBuilder()
            .setHeader(txnHeaderBytes)
            .setPayload(payloadByteString)
            .setHeaderSignature(txnHeaderSignature)
            .build();

    BatchHeader batchHeader = BatchHeader.newBuilder()
            .setSignerPublicKey(publicKey)
            .addTransactionIds(txn.getHeaderSignature())
            .build();
    ByteString batchHeaderBytes = batchHeader.toByteString();
    String batchHeaderSignature = Signing.sign(privateKey, batchHeaderBytes.toByteArray());

    Batch batch = Batch.newBuilder()
            .setHeader(batchHeaderBytes)
            .setHeaderSignature(batchHeaderSignature)
            .addTransactions(txn)
            .build();

    BatchList batchList = BatchList.newBuilder()
            .addBatches(batch)
            .build();
    ByteString batchBytes = batchList.toByteString();

    String serverResponse =  Unirest.post("http://localhost:8008/batches")
            .header("Content-Type","application/octet-stream")
            .body(batchBytes.toByteArray())
            .asString()
            .getBody();

    System.out.println(serverResponse);
  }
}