I have a application with two users and one middle man, all of them holding the private and public key, To make the secured chat, two users and one middle man are all sending the public key and generate a secured channel. After establishing the channel, the middle man doesn't have the ability to see the encrypted message unless one of the user is sending his own key to the middle man.

i am not very familiar with cryptography, so for this app i know how to encrypt and decrypt the message.

encrypt(data) {
    try {
        var cipher = Crypto.createCipher('aes-256-cbc', this.password);
        var encrypted = Buffer.concat([cipher.update(new Buffer(JSON.stringify(data), "utf8")), cipher.final()]);
        FileSystem.writeFileSync(this.filePath, encrypted);
        return { message: "Encrypted!" };
    } catch (exception) {
        throw new Error(exception.message);

but I don't know how to establish the encrypted channel from the stakeholders' key, and how can the one middle to see the message using his key and one of users' key?

is there a way to accomplish this using the cryptography?

  • $\begingroup$ So you want 2 (or more?) users to perform some key-exchange such that only they know some shared secret key. You have a "middle man" aka the trusted server that all messages (and public keys) are sent over. The server's keys are used for TLS and the client keys are managed in the browser. Correct? $\endgroup$ – cypherfox Mar 12 '18 at 10:34
  • $\begingroup$ yes, client keys are all managed in the browsers. middle man is the trusted server all messages are sent over, I think the server should know all user's public key. i am not sure whether the built encrypted channel should let the server(middleman) to send server' key in order to participate. The reason for the middle man is to make sure the chats is authorized from the server, but server doesn't see the encrypted message, unless at least one user of the chat authorize his key to the server. $\endgroup$ – user824624 Mar 12 '18 at 10:44

i am not very familiar with cryptography, so for this app i know how to encrypt and decrypt the message.

First, you shouldn't be writing cryptographic code - especially if you're not very familiar with it! Second, you'll want to use the simplest and hardest to misuse functions so you do not break anything catastrophically.

The following generalization uses Diffie-Hellman notation for simplicity; although Bob probably isn't using a Diffie-Hellman identity for TLS.

Three parties: Alice, Bob and Carol. Each have a lower case secret key and an upper case public key. $a, b, c \in \{0,1\}^n$ for an $n$ bit secret key.

Bob is the server. Alice and Carol are the clients. When Alice and Carol connect to Bob's service, Bob sends them his $Gb$ key certified by some Certificate Authority who we assume is trusted and honest. Alice and Carol verify the certification chain and are now using HTTPS.

Alice wants to talk to Carol, so she asks Bob for Carol's public key and computes the Diffie-Hellman shared secret $k = Gca$. Alice can start using this key $k$ to authenticate and encrypt messages she wants to send to Carol.

When Bob notifies Carol that Alice has tried to send her messages, Carol takes Alice' public key and computes $k = Gac$, through the associative properties of Diffie-Hellman Carol's $k$ matches Alice' $k$. Carol can now decrypt and verify Alice' messages.

AES-CBC is not authenticated encryption and is slow. Prefer AES-GCM or better AES-PMAC-SIV. Or if you're using soft-crypto only then chacha20-poly1305 is quite popular. You'll likely want to use libsodium.

Bob is a trusted server. Otherwise he can serve a malicious web page that steals Alice and Carol's keys, or more subtle may tell Alice that Carol's key is "Carol's key" which Bob knows and tell Carol that Alice' key is "Alice' key", which he also knows. Because of the power that Bob has here, Alice and Carol cannot verify Bob's honesty unless they can establish another means of communication and manually verify the service does not leak keys or messages to the server which is not as easy as you might think!

Alice and Carol do not need to be aware that any cryptography is used, but they do need secret keys that persist either in their browser's window.localStorage or better only persist in memory while the page is loaded after a user has "logged in" using a username and password. Neither the username nor password need to be shared with the server, although for convenience of finding users, the username and user's public key will likely be known by the server.

Do you want more than Alice and Carol in this key exchange? If yes, you'll want to look at N-party Diffie-Hellman. I can expand on at least one Diffie-Hellman tree implementation if you'd like.

Alternatively you may use asymmetric encryption to encapsulate keys, and send one encrypted key to each other user and encrypt and authenticate your messages using this shared group key. This does not scale as well.

If Bob cannot be trusted for "who authored each message", then you may introduce signatures.

| improve this answer | |

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.