3

I have an app installed on customers' machines, a server, and a regular website between the two. In order not to have the customers configure anything (user credentials, proxy settings...), the app communicates with the server through the browser.

To prevent any random website to communicate with the app, we have decided to implement the following automatic challenge mechanism, using asymmetric public/private encryption.

For simplification purposes, I will not talk about the browser, but keep in mind that it's the browser that passes messages between the app and the server; they both don't know directly about each other.

I have generated a public/private key pair for both the app and the server. Each one knows about the other's public key and its own private key. The app private key will be deployed on the customer's computers, so it's not "really" secret (it's a business-line application, but it's always possible that the key ends up "in the wild").

  • The app generates a random token (a guid) and sends it to the server.
  • The server encrypts the token using the app's public key, signs the (original) token using the server's private key, and then sends both to the app.
  • The app checks the signature against the token (using the server public key), and checks that the decrypted data matches (using its own private key). If they both match, the server is authorized to do futher operations.

Is it secure enough to make sure that the server is authorized to make requests? If not, how can requests be spoofed/forged, and how can I further secure it?

Update

I have since realized that this scheme does not implement mutual authentication. Since the server is not called directly from the app but only through the browser, and the browser is authenticated on the server (using WCF), is it necessary?

thomasb
  • 351
  • 2
  • 8
  • In your scheme, the server has authenticated itself to the app but the app has not authenticated its identity to the server. Also, can you clarify what are the two pieces of information being sent in the second bullet point? – vincentleest Oct 04 '16 at 14:22
  • The encrypted token, and the signed token. I'll update my post. – thomasb Oct 04 '16 at 14:34
  • Can you explain what the relation between the app and the browser is? How does the information flow happen? The app generates a token -> sends it to the website -> the website forwards it to the server -> the server signs and encrypts the token -> sends it to the website -> the website forwards it to the app -> the app validates it? – Limit Oct 04 '16 at 15:36
  • but it's always possible that the key ends up "in the wild" - they call it the Private Key cause its supposed to be private – JOW Oct 04 '16 at 15:55
  • 1
    sounds like a replay attack would work... – dandavis Oct 04 '16 at 17:32
  • @Limit: yes it works like that. JOW: yes but how am I supposed to deploy the app without the private key ? dandavis: since the app generates a new token every time, I would have thought that it wouldn't ? – thomasb Oct 05 '16 at 07:19

1 Answers1

1

This challenge response protocol doesn't really authenticate the server. Here a guid is shared with the server but the trust actually depends on the keys of the server and the client. Why not simply use those keys for communication then?
My recommendation would be to have a following mechanism:

  1. The app generates a random GUID and encrypts it with it's private key
  2. The server validates the freshness of the GUID and then creates a session key to be shared with the app. The key and the GUID are sent to the app by encrypting with the client's public key and signed with it's own private key.
  3. The app decrypts the session key and sends the GUID encrypted by the session key to the server.

This way, you have a two way authentication if you have proper replay detection in place. The use of session key mitigates the risk of your key getting exposed.

If you however want to go ahead with your approach, here are a few pointers:

To prevent any random website to communicate with the app, we have decided to implement the following automatic challenge mechanism, using asymmetric public/private encryption.

The app is totally dependent on the website. If it doesn't trust the website, how can it trust the messages that it is receiving from it?

  • The app checks the signature against the token (using the server public key), and checks that the decrypted data matches (using its own private key). If they both match, the server is authorized to do futher operations.

What if someone does an XSS on the trusted website? The script may change the IP address/identifier of the server when it sends the response to the app. This way, an incorrect server is authenticated.

In order to completely answer your question, we would need more information on your implementation.

  • Do you trust the security of the website that the app is using? An attacker my use the website as an attack vector to meddle with your communication.

  • Is the website communicating with the server using TLS?
    If it is not over TLS, any party can act as the website to the server and keep it busy with new/repeated guids.

Limit
  • 3,191
  • 1
  • 16
  • 35