Approach to pass key for crypto operations on chaincode interaction - hyperledger-fabric

I see fabric-shim-crypto library for performing encyption & signing chaincode. This suggests to pass key through transient data.
I think about another approach in which we can add it as an custom attribute in the certificate during certicate generation. This way whenever user interact with the chaincode, key can be retrieved by accessing the certificate and perfrom related crypto operation.
Which approach will be better and what are the pros and cons of both.

Second approach looks good , you can use attribute based access control lib in chaincode to achieve this

Related

Is it possible to fine-tune access control in Hyperledger Fabric private data collections further than restricting entire organizations?

In the Hyperledger Fabric Docs, while reading about private data collections I came accross this sentence regarding memberReadOnly:
Utilize a value of false if you would like to encode more granular access control within individual chaincode functions.
If I understand this correctly, this allows me to code into the smart contract specifications that will allow me to limit control to eg. specific clients of one organization instead of all peers of member organizations.
If that is so, I am curious as to how this can be done in the contract. Is there a specific way to handle access control or is it at my own discretion to write code that will enforce it? If you can provide me with any examples it would be very helpful.
To clarify what I mean, I come from Ethereum and what I am essentially asking is whether there is something like the require method in solidity, or would I just use a simple if.
Thanks for any help. If you close question for wrong site, please point me to the right place as I have not been able to find somewhere more relevant.
You didn't understand correctly.
Setting this value (memberOnlyRead) to true means that if a client sends a proposal to a peer, and the client is not in the collection, then if the peer is in the collection and has access to the data - it will refuse with an error automatically no matter the smart contract says.
If it's false, then the peer won't enforce such a thing, and then you have more freedom to code any access control logic you want for the clients.

Is there a way do add encryption to a specific value in chaincode with javascript

I want to know if there is a library for encrypting data on the chaincode for node.js, and if there is, how do i use it? or is there somewhere that explains the functions?
I've seen the chaincode encryption section in the Chaincode for Developers page, the problem is that it only explains the libraries about the Go languange (maybe I misinterpreted it).
I hade the same question before. Below is that I figured out.
Here is the library in node for the chaincode encryption section that you read in Chaincode for Developer.
This library is under development, so there is no documentation, but you can take a look at the code and some test they made. Basically, if you don't want to write to the world state with the raw value, rather an encrypted one. The chaincode invoke function takes encrypt key from transaction proposal's transient field and do the encryption. Similarly for decryption, sign/verify.
The difference between this lib and other libs (e.g: node-crypto if you write chaincode in nodejs) is that it takes keys from transaction proposal transient field. If you could manage to get the public/private key somehow, then node-crypt is enough. Just make sure to use the version that fabric supports (prerequisites).
Hope this helps.

Dynamic access control in Hyperledger Fabric

I'm working with Hyperledger Fabric, and developing Chaincode in Golang. I have the following use case and am not sure how to implement this in Fabric.
Suppose i have Bank1, Bank2, and Bank3 peer organizations. I want to design a system where they each store Client information (where client is a bank account holder). Typically, I wouldn't want Bank2 to have acess to Bank1's clients -- but if the client invokes a certain function call somehow, bank2 should be able to fetch that client's information over from bank1 (given all banks share a channel)
How can I achieve something like this in chaincode?
I've looked at ABAC, im not sure how i can update the attribute of an org to allow access to a specific client based on them having taken an action
Thank You
One solution could be to have private information outside of blockchain, and enable each bank to query it's private information by an API, directly from your chaincode, and have a shared channel among all the banks that share information through chaincode calls. Of course all APIs must be secured to be only queryble by it's own bank.
Another solution without having to implement things out of your blockchain would be to use private data collections, which is an improvement made to Fabric in version 1.2. More information here: https://hyperledger-fabric.readthedocs.io/en/release-1.2/private-data/private-data.html
Update:
Is it safe to call external apis from the chaincode? How would I maintain secret keys/tokens?
Yep, it's safe as far as you secure your communications and your endpoints. An easy solution would be to have your node and your private data store inside the same network, inside a firewall. In that way you wouldn't have to worry about security inside your applications.
To implement this using Private Data, is it possible to maybe have an array of strings which are identifiers for the banks in the Client struct, and the client can invoke functions to allow more banks, and when banks try to query a Client the code checks that array if the bank's identifier is included there or not?
It seems to me that you are in the right direction, but I would implement it as a JSON file, more than an array with access rules, stating that for BankA, BankB has access to this and that functions and so on, and also you can set levels of visibility in the information, and then implement the logic that reads and uses that config in your chaincode. In production, each node will have to have its own config file, but for development you can have a single config file with all the rules.
Update 2:
Is it possible for someone from an organization to 'query' the ledger or read it's state directly and NOT through the chaincode?
Short answer: yes, it is possible. Whatever gets written in the blockchain, would be readable by administrators of peers, and anybody who has control over private keys. BUT here is where architecture comes into play: if you don't need something written in the blockchain, just don't write it. It depends on what you want the blockchain for. If it's just to attest that an information has been shared, just save the necessary information: 'bankA shared info about userB with bankC'. The actual info doesn't have to be saved in the blockchain. If you need to have the info in the blockchain and you want to keep it private, I think the best solution is using private data collections, and be awared that in fact private data is not subject to consensus, because private data gets saved in a side DB only in the peers/organizations involved in the private transaction, not in every peer.

Generate a sufficient secret for JWT NodeJS Lambda

I've been looking at implementing JWT for the first time using jsonwebtoken (https://github.com/auth0/node-jsonwebtoken). For that, I need a secret value.
Is there a recommended command, or site, to generate a sufficiently good one?
I found this page (https://security.stackexchange.com/questions/95972/what-are-requirements-for-hmac-secret-key) which goes into detail about how long a secret should be (the answer seems to be a 256-bit), but where do you get one from? :)
Else it seems the other option would be to use a public/private key pair. They seem to prefer that approach on this guide I found: https://medium.com/#siddharthac6/json-web-token-jwt-the-right-way-of-implementing-with-node-js-65b8915d550e since that guy says he started off using a string and then switched to using a key pair. However the complication is this will be running on Lambda so I would ideally like the secrets (string or key) to be in environment variables. Not kept as files. But if you put a certificate in an environment variable, I wonder if AWS will strip out newlines and so screw it up when Node tries to work with it. So I'm thinking a secret string would be simpler - as long as it is sufficiently strong.
Thanks!
This is what I did when implementing HapiJS with JWT2. I generated a key based on the documentation they provided. According to their repo, this is one of the simplest ways to generate a secure key to sign against for JWT.
node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"
I don't think you have to use asymmetric key authentication with public/private keys for JWT. In simplest forms, when a user logs into your system, they are given a hash of user data. On the client side, you provide that hash in the authorization header with each request. The server will check the hash to verify integrity. Since you have the key that you hashed against, it's highly unlikely that they will be able to create a forged hash.
Check out this link to the GitHub issue where they discuss generating keys for Hapi-auth-JWT2.

How to retrieve transaction from Hyperledger fabric network for Audit?

I would like to retrieve all transactions from the Hyperledger fabric netwrok for assurance. Please guide me to how retrieve transactions from all the peers to validate and completness of the transactions ?
Thanks in advance.
I think it depends on your business requirement. For audit purpose, it's more likely you want to know transactions about a specific asset(key/value). You can query history of a specific key using the GetHistoryForKey() shim API. A transactionId is contained in the response. Then you can query the detail by the transactionId.
In addition, there are some query apis provided from the Fabric SDKS. For instance, the NodeSDK. In the Channel class, there are a bunch of apis like queryInfo, queryBlockByID, queryBlock, and queryTransaction etc. The fabcar sample provides some NodeJS code you can follow up to create your own queries.
Finally, you can also inspect the ledgers (file based) directly from peer node. By default the path is /var/hyperledger/production/ledgersData/chains, within which there are ledger files per channel. To inspect the files, you may need to investigate the FileLedger impl. With some initialization work, you can inspect every block, the hash, the transactions and the Read/Write sets in detail. Hope this is helpful to you.

Resources