Search code examples
hyperledger-fabricx509certificateprivate-keypublic-keyecdsa

Get client's signature from the Hyperledger Fabric block and verify it


In Hyperledger Fabric, the client signs a transaction using the private key. I am trying to find this signature from the block and verify the sign using client's public key.

Code to fetch signature in nodejs:

let getBlockByTX = await blockContract.evaluateTransaction("GetBlockByTxID", channelName, txId);
const resultJson = BlockDecoder.decode(getBlockByTX);
let signaturePRVKey =resultJson.data.data[0].signature;

Output:

signaturePRVKey in base64 format
MEUCIQC330iICU/FP1XCIsYIHl4e6ytuS9niir/J7lZ5J5kYegIgF0zvjObCXMnrJfA+QXzIbbuJfJfx0ld+Wv6GknSX3fg=

signaturePRVKey in hex format
3045022100b7df4888094fc53f55c222c6081e5e1eeb2b6e4bd9e28abfc9ee56792799187a0220174cef8ce6c25cc9eb25f03e417cc86dbb897c97f1d2577e5afe86927497ddf8

I want to know, is signaturePRVKey giving me the correct signature?

For Signature(signaturePRVKey) verification using jsrsasign library:

const data = [
    "p1","Alice","F","[email protected]","02156874652",
]

var sig = new KJUR.crypto.Signature({ "alg": "SHA256withECDSA" });
sig.init(certificatePEM);

sig.updateString(data)
var isValid = sig.verify(signaturePRVKey)
console.log(isValid)

signaturePRVKey verification using client Certificate return false. Please Let me know how can I fix this.


Solution

  • The BlockDecoder unpacks the raw protocol buffer message structure of the block into a plain JavaScript object structure. The result you get from it is not in a form that allows you to verify the signature. Bear in mind though that the signature will have already been verified as part of the transaction submit process. If the signature is invalid, the transaction will be rejected.

    If you do want to verify the signatures yourself, in the original protocol buffer message structure of the Block, each element of the Block's data.data array is the serialized bytes of an Envelope. The Envelope contains a signature property (which you are successfully retrieving) and a payload property (which is the serialized bytes of a Payload protocol buffer message). The signature is the digital signature of the payload. This can be verified using the signer's public key.

    Note also that the Payload itself contains within it a SignatureHeader, and the creator property of that SignatureHeader contains both the Member Services Provider ID (MSP ID) of the signer and also their id_bytes, which will typically be the signer's X.509 certificate in PEM format. The X.509 certificate contains the signer's public key.

    If you want to do this signature verification then you need to work directly with the protocol buffer message returned by GetBlockByTxID, not the output of BlockDecoder. There are published packages containing the generated language bindings for the Fabric protocol buffer messages that you can use for this purpose:

    https://hyperledger.github.io/fabric-protos/

    There are examples of these packages being used to unpack Block protocol buffer messages in the off_chain_data sample:

    https://github.com/hyperledger/fabric-samples/blob/main/off_chain_data/application-typescript/src/blockParser.ts