1

First I thought I could easily use private like:

mapping (address => bytes32) private userPassword;

and so just check if the entered password is right:

function enter(bytes32 password) {
   if (password == userPassword[msg.sender])
      //do smth
}

But then I read this in solidity docs:

Everything that is inside a contract is visible to all external observers. Making something private only prevents other contracts from accessing and modifying the information, but it will still be visible to the whole world outside of the blockchain.

So if I got it right, even if I use "private" visibility still everyone can see values of stored passwords. Then how should I store information that shouldn't be for public?

3

Users (contracts, trusted machines, other contracts) are identified by their Ethereum address.

Instead of storing their passwords, use msg.sender to authenticate.

Since you don't want anyone participating without authorization, you need a list of addresses that are authorized. You create add/remove user functions and you ensure that only the authorized admin (usually called owner) is allowed to access those contract functions.

The access control list would be a list of ethereum addresses.

Some organizational ideas here: Are there well-solved and simple storage patterns for Solidity?

And here: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a

Hope it helps.

  • But what if I don't know who will join my contract? I just want to give someone password so he could easily enter just using it. Because I don't know in advance his Ethereum address to authenticate him. – porfavorite Jul 4 '17 at 19:00
  • 1
    If you are giving a password to "someone" (i.e. a specific person), you could just as well ask that person to give you his/her Ethereum address. On the other hand, if you want to post the password somewhere from where people could look it up without having to contact you, then they are not really being "authorized" by you. – Ajoy Bhatia Jul 4 '17 at 19:10
  • 1
    It takes some time to adjust to the way Ethereum is meant to be used. it will change the way you approach certain problems. – Rob Hitchens - B9lab Jul 4 '17 at 19:17
  • Can you plase thell me the way I can check contract's values? I just read that everybody can watch it, but don't know how. Thank you. – porfavorite Jul 4 '17 at 21:51
  • 1
    Possibly a little too much information, but ... ethereum.stackexchange.com/questions/765/…. Also, since miners verify all transactions that would change the contract state, it's safe to say that those transactions are witnessed by all verifiers. Transaction payloads are visible to everyone. Jacob's idea using hashes is viable and suitable for some use-cases. In most cases, it's better to use Ethereum's natural way to do authentication. Hope it helps. – Rob Hitchens - B9lab Jul 4 '17 at 23:01
1

If I understand correctly your requirements you may implement the following approach:

  1. Generate passwords for all of the invited users and send them out.
  2. Store in your contract hashed values of these passwords using keccak256 algorithm (you may do so with javascript library ). Remember to hash them off-chain and send final values to the contract.
  3. Ask invited users to reveal the received password. Hash it on-chain using keccak256() solidity method and if the hashes are equal allow a user to join your contract.
  • Won't hashing the password on-chain in step 3 reveal the password? – lungj Jul 4 '17 at 17:51
  • Yes, it will reveal the password. I even used the word reveal to avoid any confusion. Following the question author's explanation: " join my contract only using the password" you may view my solution as a ticket to join a contract that is validation during the reveal phase. – Jakub Wojciechowski Jul 4 '17 at 17:56
  • To make good hashed value I need to use some 'info' (block number or smth) besides the password. And if I want to get the right hashed value after encrypting recieved password, I need to store this 'info'. But as I see it is impossible. – porfavorite Jul 4 '17 at 19:08
  • 1
    If you are hashing common values like words or small numbers you need an extra piece of randomness which is called salt to protect against reverse hashing. That's why there is often a use case for block number to be added to hashed value. But if you are already generating long enough random password I don't suppose there is a need for external salt. – Jakub Wojciechowski Jul 4 '17 at 19:36
  • thank you, that makes sense. If there is no better way, have to do something like that. – porfavorite Jul 4 '17 at 19:41
0

Don't store passwords as advised use msg.sender to authenticate instead

  • But what if I need new user to join my contract only using password? So that not everybody could join, only who got password from me. And what to do with other information, for example, some documents information like passport info and etc. – porfavorite Jul 4 '17 at 16:36
0

As Jakub pointed out you can use keccak256 to store and verify secret passwords. Two problems with this method:

  1. Supplying the plaintext password during access will reveal it to anyone monitoring the pending transactions pool. An attacker can then race your user and use the password by generating a corresponding transaction and specifying a higher gas price which will get executed earlier than that of your legitimate user.

  2. Once the password has been used it is no longer secret.

There is nothing you can do to mitigate 1. aside from using a prohibitively high gas price to begin with when using the password.

To mitigate 2. you can require the user to generate and specify a new password hash that has to be send along with the password creating a new one use password for next time. Rinse repeat.

0

If I understood your question correctly,

Contract Deploying account should know the allowed users, well in advance or after deployment.

For your case knowing all the users while deployment is rolled out.

Other option is to allow everybody to requestRegister, have a eventTrigger from that, run your one time authentication logic and register the sender address in the list of allowed users.

With this further tracking of allowed users are ease and any time user addition also possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.