Neon-js; user friendly key management

Hey everyone,
I’m happy about this new COZ forum. Hope we will all have a good time here together.

Anyways, I’m currently working on an NFT game and currently iterate on the fighting system. The next step will be an iteration about the blockchain integration. Currently, the system support Neo 2, but as N3 is getting closer and closer a switch towards N3 need to be done.

One of the weaknesses of the current integration is how transactions get signed on the client side. Short summary of how the system works at the moment:

  • user signs up for the game
    – set username
    – type a password
    – click create keys, which creates an encrypted key and address based on the typed password
    – click sign up (to store username, encrypted key and address - password isn’t stored!)

  • user log in to the game
    – type username (refers to the stored encrypted key)
    – type password
    – client receives the encrypted key and decrypt the key with the typed password
    – the resulted address gets submitted to the server and is compared with the stored address - if they fit the user can login
    – if login is successful password gets stored locally in the clients browser

  • sign a transaction
    – password is stored client side
    – for a transaction the player gets the encrypted key from the server, decrypt the key with the password and signs the transaction with the key

The biggest vulnerability is the client side stored password, which I’d love to get rid of. No solution for me would be to use a 3rd party tool, which need to be installed on the clients browser to manage the keys. For blockchain newbies this step is a pain regarding UX.

I’m happy to discuss the topic with you guys.

2 Likes

Ideally a user wouldn’t need to sign up for the game at all - their Neo address can be their user ID in most cases.

You connect to NeoLine or O3 via dAPI to get their address (where they see a popup and click approve), and then they are just “signed in” to the dApp - no passwords or other authentication required, and nothing confidential that needs to be stored in the browser.

https://neoline.io/dapi/

If you want to let them set a custom short username that other players could see or change other globally visible user profile settings, they could sign a message with their private key to authenticate that action, then the dApp could verify the signature using their public key as reported by the wallet.

3 Likes

Thanks @hal0x2328, but your suggestion is exactly one that I would like to avoid. Forcing users to use a third party tool isn’t what I’m looking for. For blockchain native people it wouldn’t be a big deal, but the target group of the game isn’t essentially already part of the blockchain space. The setup currently in place focuses on not making a big deal out of the blockchain integration.

The game I’m developing is mainly a pure off chain game. Only items are represented on the blockchain as NFTs. Most of the time there isn’t any real touchpoint with the blockchain. Tasks with touchpoints are:

  • learning a recipe (send recipe NFT to server address to take the NFT out of the game)
  • crafting an item (send materials to server address to take them out of the game)
  • transfer items between players

With crafting an item, there are several transactions involved. So, a player would need to confirm several transactions (dialogs in the 3rd party tool) to accomplish this task. This again wouldn’t be good UX.

Therefore, I would really like to go with the presented “flow”. Mainly I think I’m asking for how I could improve the password handling at the client side.

I don’t think there’s a solution that will accomplish what you want, then. If there will be a need to sign transactions and also hide that UX from the player, some component will need to cache the key or encrypted key+password.

The best you could do is encrypt the password with a per-session key, but if someone wants to write some malicious code to steal the password from the browser, they can just grab the session key as well, or just inject some code that will wait and grab the password and/or private key after it is decrypted.

There’s really no way to make embedded blockchain transactions both completely safe and transparent to the user at the same time.

1 Like