Unable to understand PKI concept in Hyperledger Fabric? - hyperledger-fabric

I am just starting Hyperledger Fabric. I was reading about PKI concept in Hyperledger fabric.I am reading form this link
Below is the diagram they explain Marry uses her private key to sign the document. But in general its is explain in this link
that public key is used for encryption.
So which key is used for encryption ?

There are various aspects to Asymmetric Cryptography. A confidential message can be encrypted and disseminated over the network in various ways. Let's assume there are two participants in the network - A and B, each of them have registered themselves with a certificate authority and have obtained their crypto pair - a public key and a private key. Now, if A wants to send a message to B, he has two options
encrypt the message M using his private key and send. Now, if B has
access to A's public key over the network, he will be able to
decrypt the message. Now, assuming A's public key is generally
available over the consortium network, people other than B also will
have access to A's public key. Now, does this compromise the message
integrity? Well, no. This is because the encryption is a function of
the private key as well as the message, so people having the right
access can decrypt and see the message but will not be able to
tamper it unless A's private key is compromised.
Another way in which A can send message to B, is by encrypting it
with B's public key. Now, this message can only be decrypted only by
B and whoever B chooses to share his private key with in a secure
manner. Here, again the encryption will be a function of B's public
key and the message - that said the integrity of message can be
assured.
Hyperledger Fabric follows the first method - the messages are encrypted by sender's private key and recipient's access to the sender's public key or to the message per say is managed by by consortium/organization's membership, access control rules and channel policies.

Related

Hyperledger Fabric Data Confidentiality

I did not find a good tutorial or article answering this question so far, maybe you can help. What I want to do is the following:
Peer A in Org 1 calls chaincode, this chaincode has access to data only available in Org 2 and Peer A never gets access to the full information.
I know that Hyperledger Fabric supports private channels and private data, is it possible to achieve this requirement? If yes can you point me in the right direction to do this?
Yes, it is possible. below are the steps to accomplish.
By using private data, you can accomplish your requirements, but little work needed. you an also follow the fabric documentation, i have provided the links here.
The client application submits a proposal request to invoke a chaincode function (reading or writing private data) to endorsing peers which are part of authorized organizations of the collection. The private data, or data used to generate private data in chaincode, is sent in a transient field of the proposal.
The endorsing peers simulate the transaction and store the private data in a transient data store (a temporary storage local to the peer). They distribute the private data, based on the collection policy, to authorized peers via gossip.
The endorsing peer sends the proposal response back to the client with public data, including a hash of the private data key and value. No private data is sent back to the client.
Check this for endorsement: https://hyperledger-fabric.readthedocs.io/en/release-1.4/private-data-arch.html#endorsement
The client application submits the transaction to the ordering service (with hashes of the private data) which gets distributed into blocks as normal. The block with the hashed values is distributed to all the peers. In this way, all peers on the channel can validate transactions with the hashes of the private data in a consistent way, without knowing the actual private data(This is what you need to accomplish).
At block-committal time, authorized peers use the collection policy to determine if they are authorized to have access to the private data(For reading the block data). If they do, they will first check their local transient data store to determine if they have already received the private data at chaincode endorsement time. If not, they will attempt to pull the private data from another peer. Then they will validate the private data against the hashes in the public block and commit the transaction and the block. Upon validation/commit, the private data is moved to their copy of the private state database and private writeset storage. The private data is then deleted from the transient data store.
Resources: https://hyperledger-fabric.readthedocs.io/en/release-1.4/private-data/private-data.html

Fabric - Data encryption

Is it possible to encrypt the data directly inside the chaincode?
What I'm trying to do is to hide data between participants without using the channels.
For example:
The network have three participants A,B,C
The chaincode holds the public key of B which is used to encrypt the data.
A and C send data to the chaincode which store the data encrypted with the public key of B.
B with his private key can decrypt the data retrieved.
Is this way a secure way to encrypt the data? Could work?
Thanks.
There is a Fabric example for symmetric key encryption, see the doc and an example.
A similar mechanism could also be used for asymmetric encryption as you propose. However you may want to encrypt the data on the client side, and then pass the encrypted data into the chaincode.
Alternatively, you could use the private data feature to pass the private data to peers of authorized organizations. The other organizations would only receive a hash of the private data in the block transaction. For more details see the private data documentation.

When creating a block through a transaction, is it proper to write the device's private key as a signature on the block?

I want to create a block-chain environment for devices.
When creating a block through a transaction, is it proper to write the device's private key as a signature on the block?
Never (ever) reveal the private key for anything - person, phone or device. The public key is what is shared with other parties.
WRT blockchain and especially Hyperledger Fabric, transactions submitted are signed with the private key and the signature is actually around a transaction containing the public key.
That's a huge security flaw and defeats one of the key benefits of BC. Look at your private key as your private password to your bank account, laptop, phone among others. You definitely don't want anyone know about it.
Short answer, No!
Happy coding.

Using Public/Private key pair as proof of delivery

The problem
I'm working on a mobile application where user A should physically delivery something to user B, and the user A MUST prove that delivered it.
There is a restriction:
User A or User B might be offline on the delivery, so it can not rely on internet connection
My approach
I thought about using cryptography to solve this problem:
When the delivery is scheduled, the following process occurs:
A key-pair is generated, and stored on database.
The private key belongs to User B and should be transfere to his mobile app.
Some well-known+delivery_uuid string is encrypted using the public key, and transferred to the User A.
User A is oriented to only show the encrypted code (in form of a QRCode) if the delivery occurs.
User B is oriented to read the QRCode using the mobile app when delivering.
Since the encrypted message begins with a well-known string, the User B mobile app can decrypt it and verify that the message is OK. The application store the delivery_uuid part if valid, and sends to server-side to keep track as soon as user get internet access.
If the User B try to fake the delivery_uuid, it will obviously not match.
If the User A try to fake the QRCode, the User B's app will not be able to validate the message.
Concerns
The fact of a well-known piece be present on every encrypted message can make it weaker? Considering that the key-pair is used just once.
The public key should NOT be visible to anyone. Only the back-end must use it to create the delivery proof message. Same obviously apply to the delivery_uuid
Sh*t happens. If the user B mobile app somehow crashes and loose the delivery_uuid before sending it to back-end, the user B will need to rely on user A honesty.
How strong must my keys be? Considering the monetary value of the package is low. Is RSA the better encryptation in this case?
I really know that this question is complex, but I really appreciate if someone can help-me with it.
Note: I'm not sure that Stackoverflow is the right stackexchange community to ask about this, please comment if it's offtopic. But since it have something about logic, I think that's the right place.
Seems a little complicated. Why not
UserB (and every user who installs the app to receive deliveries) is issued a public/private key pair. The private key is held only by UserB; if it is lost, a new pair can be issued. Meanwhile, the public key is public, and is stored in a database along with UserB's identity.
Upon receipt of the delivery, UserB generates a simple text document containing the date and time, the QRCode, the name of the person receiving the package, or whatever information is needed. The document also contains the public key. Any format will do.
UserB signs the document with his private key and appends the signature to the end of the document. Now you have a cleartext document spelling out everything that happened, and proof that UserB agreed to it.
UserB shares the document with UserA, and/or uploads it anywhere that is needed, e.g. system of record. Both UserA and UserB can keep an offline copy.
If proof of delivery is ever needed, UserA just needs to produce the signed document.
If I understand the problem correctly, there are three parties here :
The verifying party, which is your back-end.
The selling party, which is User A.
The buying party, which is User B.
Also I do not buy the idea that "The public key should NOT be visible to anyone". They are meant to be, that's why they are called public.
Now, In order to make sure that the item was delivered
By User A
To User B,
We can have the following setup.
The verifying party ( i.e. the backend ) generates a token, associates it with the buyer, the seller, item and persists the info.
The verifying party encrypts the token with User A's ( seller ) public key.
The verifying party encrypts the already encrypted token with User B's ( buyer ) public key.
The verifying party sends the double encrypted token along to User B. Since it has been encrypted with User B's public key, only User B can read it.
User B decrypts the double encrypted token using his private key and saves the result in his device. The result is now encrypted with User A's public key, which means only User A can read it.
When User A comes to deliver the item, User B hands over the encrypted token as acknowledgement. This can be done via a QR code scan.
User A decrypts the encrypted token with his private key and keeps it in the device.
Whenever it is feasible ( in terms of availability of internet ) to prove it to the back-end, User A encrypts the token with the backend's public key and sends it along to the back-end.
The back-end decrypts the encrypted token with its private key and does a lookup in its persistence store, matches the buyer and the seller and completes the verification.
Use signatures and not encryption.
0) The app, as distributed, contains the public portion of a keypair only the server knows.
1) Every user that installs the app generates a keypair, keeping the private key, and uploading the public key to a database.
2) When a delivery is scheduled, the server generates a delivery ID and creates a message containing:
The Delivery ID
The deliverer's (user A's) public key fingerprint.
The recipient's (user B's) public key fingerprint.
A will receive this message and signature prior to making delivery. B can, but need not receive it prior to delivery.
3) When A meets B, A can off-line transfer the message and signature to B. QR code would be difficult, depending on key size, but NFC would certainly work. B can verify the server signature and know that the message has not been falsified or tampered with. A can transfer his public key to B and B can verify its fingerprint via the signed message. A can prove he is who he says he is by creating a signature with the private key belonging to the public key that was just transferred and verified.
4) B can prove who he is by creating a signature with the public key matching the fingerprint in the delivery message. B would have to transfer his public key to A if A didn't already have it, and A can verify it matches the fingerprint stored in the message.
5) B can certify receipt by creating a signature on a message saying so (however you want to format that) and off-line delivering it to A. A can then present this to the server, which the server can verify because it has B's public key.
Let's assume that:
- A has a key pair.
- B holds a delivery UUID.
The goal is to enable B to provide a proof that only A can provide.
As previous answers this can be solved by digital signature. You should let B and A to enchange the necessary information. B should provide the delivery Id, and A must sign it.
You need to hold the public keys of the partners.
You need to provide a way for the information exchange, bluetooth perhaps?
I believe that you may need more than this simple protocol.
After reading the answers, I've formulated a solution to the problem. I'm posting it as answer to know from everyone comments about it validity.
First, let give names to the actors to simplify:
User A is the Seller
User B is the Buyer
The use case
The buyer decides to buy, and make the payment. Now he talk with the seller to combine the delivery.
After payment confirmed, the back-end generates an UUID , and associate it with that transaction_id. Let's call it delivery_uuid. By the business logic, only the buyer have access to it.
The buyer app requests the delivery_uuid to the back-end, which produce a message containing both the delivery_uuid and the transaction_id, then digitally sign this message. Lets call this delivery secret
The buyer app will keep this message in storage.
When both seller and buyer meet, and the buyer checks if the product is OK, then he gives the delivery secret, using a QRCode or NFC.
With the delivery secret in hands, the seller's app can check the delivery secret authenticity (using the application's public key), then store it to send to back-end as proof of delivery as soon as he have internet access.
Now that the back-end have the proof of delivery, the payment to the seller is made.
Considerations
Buyer signature to the message
I think that it's not necessary, since by the back-end conception, only the buyer have access to the delivery secret. If the delivery secret leaked, certainly I'm in a bigger trouble.
Seller signature to the message
Also not necessary, the only concern about the seller is that he needs to send the delivery secret to the back-end. If he loose the cellphone, that's not our problem. If the application crashes and the delivery secret is lost, then we have a problem.
Server signature
This signature allow the seller to make sure that the delivery secret
Belongs to the right transaction, preventing the the buyer to use an authentic delivery token from another transaction.
Have a valid delivery_uuid
Make sure that delivery secret is still valid (we may add a validity to it)

In Fabric, how the key used for data encryption is supposed to be shared?

With FAB-830 implemented in Fabric v1.1, it is now possible for the chaincode to encrypt the data stored in the state.
The idea is: the symmetric encryption key is passed as a transient parameter and is therefore only known to the endorsers.
This allows to run business logic on clear data and upsert encrypted data (such on-chain encryption is impossible in Ethereum and most other blockchains AFAIK).
The part I still miss is: how the organizations which are supposed to share the secret get to know the symmetric key?
Also, even if the endorser get the transient key from the sender as part of the transaction proposal, is there any out-of-the-box way to store it?
Many thanks in advance.
The peers/endorsers should not actually store the encryption key. The idea is that the encryption key(s) are managed at the application level and only passed to the peers as required (generally when executing contract logic and not necessarily needed for querying data as the decryption can be done in the application rather than on the peer(s)).

Resources