Steem Messenger: improving the cryptography for better interactions
Pull request merged: https://github.com/kingswisdom/SteemMessenger/pull/15
The project so far
Steem Messenger™ is about convenience, security, and privacy. Many Steem users decided to use chats mediums like Discord, and Steemit.chat. Steem Messenger enables a secure and fast instant messaging interface between users on the Steem blockchain, without the need to trust your recipient, or any other third party.
To make this secure and private, they use the Steem Memo function. All data are end-to-end encrypted between users and super-encrypted between users and server. Users should not trust the server more than necessary.
This project is more than messaging as it allow to make file transfer.
Same ideas, better Cryptography
This update is about reassessing the cryptographic design of Steem Messenger. I reviewed the previous implementation, discussed with the PO to see what goals we want or may want to achieve and prepare the code for this new direction.
The Steem Messenger server, called Lara, needs to authenticate the users to deliver the correct (encrypted) messages to them. The previous implementation sent the private key with the public so that the server could make the verification. There is actually no need to leak your key to the server. A simple challenge-response where the user signs the challenge would have been better. I decided to do instead a Diffie-Hellman (DH) key exchange between the user memo key and the server memo key because, as a paranoia rule, you should not mix the usage of a key. Since the memo key is used for DH and encryption with the resulting shared key (ECIES), I decided to stick to that usage. We can then derived authentication and encryption keys from the shared secret from the DH. There are interesting advantages:
- note that the memo keys(server AND clients) are retrieved from the steem API.
- we can easily add ephemeral keys in addition to the, long term, memo keys. We would get Forward secrecy that way.
- we can derive authentication keys that can be extended to short term session keys.
- we can generate symmetric encryption keys and optimize the overall speed of communication.
We use the following protocols:
- Diffie-Hellman on Steem curve (same as Bitcoin: secp256k1)
- AES-CBC (under an ECIES like setting)<-- it will be replace by a simple AES-GCM with shared (session) key generated before
This code implements the following features:
- create a
cryptomodule to regroup all the functions
- uses steem-js crypto as subfolder(the git submodule did not work. see.
- stop sending user private key to server for the authentication
- instead create a shared secret from user memo and server memo keys
- add a fix hmac derivation (this can be easily extend to have session keys)
- note: users can now authenticate the server (Lara) the same way they are authenticated by the server (not implemented yet)
- prepare switch from memo encryption(which is rather slow because of elliptic curve Diffi-Hellman for each encryption) to AES-GCM encryption (this will improve the overall speed)
- clean all the places we send the private key to the server
- clean up the logs
- move the key storage from cookie to local/session storage
- add key storage encryption
- use Ephemeral DH
- use one crypto library instead of many. There are currenctly some cryptographic function in steem-js and some in steem libcrypto. I may need to add functions to one or the other but there is no guarantee they will be accepted and merged fast enough (seeing how little activity there has been).
- copywrite a whitepaper/wiki to explain the whole philosophy and design of Steem Messenger.