Web application and public-key encryption

I use Publisher/Subscriber pattern on top of WebSockets in my home automation software. Integrated server add topics into in-memory database for every sensor, relay, etc… Events from the controller are published into topics and all the clients subscribed into topics get realtime updates from the controller. I can easily write 8th client program but how to securely manage private key with web browser client? Are there good enough JavaScript ed25519 libraries?

My idea for secure communication is to make client send it’s public key to the server. The server creates a shared secred (servers private, client public) which it uses to encrypt a session-key to the client.

If the client is sending an invalid public key, no communication is possible and the server drops the connection.

If the client is sending a valid public key, it knows the shared secred (servers public, client private) and uses that to decrypt the session key.

Now, session key can be used for encryption/decryption. Session key will always be random, because it’s not possible for anyone to guess what that is.

Any ideas?

Basically yes

Each end knows its own private key
Any one can know the public keys

So if the client encrypts a message with its private key it can be verified that it IS the correct client by decrypting the message with the public key. That public key can only decrypt messages encrypted with the matching private key.

Then you do the reverse

WHAT gets encrypted can be anything - even a known shared “secret” because the private / public key pairs prevent anyone from using a different private / public pair that would encrypt & decrypt in the same way

I would suggest handling encryption and identity verification separately.

e.g. Here’s how SSH handles public key authentication:

  1. Insecure connection established (TCP, websocket, etc.)
  2. Each side generates a random encryption key pair, exchanging the public halves
  3. Each side generates the session encryption key using the exchanged public keys
  4. The session is now encrypted.
  5. Server sends a block of random data to the client.
  6. Client SIGNS the data with their long-term signing key.
  7. The server uses the public half of the client’s signing key to authenticate the signature.
  8. The client has proven its identity.