For a product I'm developing I want to verify if the thinking behind it is cryptographically strong and secure. The product is a chat widget on websites of customers. Like an e2ee version of Intercom.

There are 3 parties that will connect to the service:

  1. Customer of the service (i.e. user of the service I will offer)

  2. Service that offers the chat widget + tools for its customers

  3. Visitors are people that use the chat widget

A few features that are important for the product are:

  • The service should not see the content of messages send between customers and visitors
  • The traffic between service and customer and visitor are encrypted via SSL. In this product only important the service can't read the messages
  • The visitor does not have an account with the service
  • The customer has an account with the service
  • The customer can reply to chats from multiple devices
  • The encryption and decryption should be done in the browser of the customers and visitors only. It will rely on the SubtleCrypto API
  • The messages include a session ID so both users can verify if following messages are from the same sender

I created a diagram with all the steps I think I need to take:

enter image description here

Diagram explained

  1. To be able to use the same public key on multiple devices of the customer it needs to be copied to other devices of that same customer.
    • The customer logs in the service with their password
    • We use the password to create a PBKDF2 key in the browser (key stretching)
    • We generate a RSA key pair
    • We encrypt the private key with wrapKey with the PBKDF2 key with AES-GCM 256 bits (the service will not have access to the decrypted private key)
  2. Send the encrypted the private key and public key of the customer to our service
  3. The visitor also creates a key pair with RSA-OAEP
  4. The visitor sends the public key to our service
  5. The visitor gets the public key of the customer from our service
  6. The visitor includes a session ID in their message and encrypts it with the public key of customer
  7. Visitor sends encrypted message back to service
  8. Customer receives encrypted message and public key of visitor
  9. Customer decrypts message with their own private key and encrypts message for the visitor with their public key
  10. Encrypted message is send from customer to service
  11. Encrypted message is send from service to visitor
  12. Visitor decrypts messages from customer

Known flaws

  1. The customer can't verify who the visitor is unless the visitor identifies themselves. This is totally fine for our service

What are there other cryptographic flaws in this e2ee service?

  • $\begingroup$ 1) This question is rather about software development or security, but not about cryptography. That's why it is off-topic here. 2) It is not e2ee. To make it e2ee, encryption and decryption should happen on the ends of connection, not in the middle. What you suggest is man in the middle. Even if you don't mean anything bad, but actually you can read and modify any messages. $\endgroup$ – mentallurg Apr 18 at 21:39
  • $\begingroup$ Send the encrypted the private... - If you require that somebody send his private key to you, you make your communication not trusted. What is the purpose to use primary key then? In a normal case, when only the owner has private key, anyone who receives a message signed by him knows, that this message come really from him. Also, anyone who encrypts a message to him knows, that nobody except receiver can read the message. Where as in your case you can sign any messages in the name of one side (because you have their private key) ans you can read also messages. $\endgroup$ – mentallurg Apr 18 at 21:53
  • $\begingroup$ If participants of such communication accept that you can read and modify their messages, then why overhead with keys? Just use symmetric encryption with a new key for each chat session. $\endgroup$ – mentallurg Apr 18 at 21:53
  • $\begingroup$ @mentallurg, Thanks for your comments. I don't get your point about man in the middle. Encryption and decryption happens on the ends of connection, not in between. Also, sending an encrypted private key makes it unusable for the man in the middle, right? It will be encrypted with the password of the customer (which the service doesn't have, see step 1). If the service can read the message then SSL encryption would be enough. That's not what I'm looking for. $\endgroup$ – adriaan Apr 19 at 10:34
  • 1
    $\begingroup$ You wrote "sending an encrypted private key makes it unusable for the man in the middle, right?". No. Namely this is a problem. Your service is a man in the middle. Your service can read and modify any messages that both parties send to each other. Your users should be aware about this. For many of them this can be very important. For instance if users want to reach customer service of some bank to discuss sensitive questions, your service will be not acceptable, because you can read all their messages. $\endgroup$ – mentallurg Apr 19 at 13:56

If the customer sends his public key to the business, then the business creates a new set of keys forwarding the new public key to the visitor then the business now has a way to decrypt messages from the visitor since the visitor is not aware that the public key is not the intended customers public key but the new one generated by the business. The business now can decrypt all messages from the visitor to the business making any changes they wish and using the customers original public key to re-encrypt the changed message with the customers public key and passing that message along to the customer who is not aware that the message has been changed. If the business does this with the public key of the visitor passed to the customer as well then messages can be read and changed in the opposite direction as well. This is a classic man in the middle. That is what TLS is designed for an encrypted communication channel directly between the visitor and the customer with no relay between the certificates for TLS can be verified through a certificate authority which both parties have to trust for the initial key exchange to take place. In this scenario the business is trying to act as a trusted man in the middle however it maybe the intention to have the business act as a certificate authority who signs both the businesses and visitors certificates or public keys to ensure that both parties are receiving the intended keys. In order to do that both parties should have the businesses certificates installed as trusted certificates authorities on their systems which is not a great idea and can lead to major compromises in practice.

| improve this answer | |
  • $\begingroup$ Thanks for your answer! How would you solve this issue for this kind of application? $\endgroup$ – adriaan May 7 at 10:38
  • $\begingroup$ I guess this can be solved by letting the business save an SHA1 hash of their public key in their DNS settings of their website. That way you can verify it's somebody from within the company and not the middle man. There is always a way for the middle man to get the original data (Facebook could still access the messages in the app of WhatsApp itself and send it back to their servers). But it's hard to do this unnoticed in a open source web application. $\endgroup$ – adriaan May 16 at 7:48

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.