How to make secure communication between servers

I need to application 1 make a POST on application 2, but on application 2 I need to make sure that POST comes from the application 1.

For the purpose of this post, I'm going to call application 1 the Client, and application 2 is the Server.

Let's start with:

My biggest worry is Man In The Middle attack.

Ensure that when the Client makes a connection to the Server, the client must confirm the identity of the Server, and ensure there is no Man In The Middle. (MITM) This is the same problem browsers face when trying to make a secure connection for Online Banking or other sensitive operations.

  • This is easily secured using a standard HTTPS certificate (which would use TLS encryption). The connection is secured by using Asymmetric Cryptography, such that the only way to accomplish MITM would be to steal the private key from the Server's filesystem.

    A certificate can be issued from a Certificate Authority with renewal every few years, or you could create a self-signed certificate stored on the Client system at no cost.

Now with Server identity, and MITM successfully thwarted; you need only to verify the identity of the Client. There are several ways to proceed. Pick one

  1. Shared Secret: simply include a password on the Client machine, and the Server must verify that it is matched. This is the most straight-forward way to verify client identity, and is safe thanks to HTTPS.

  2. Client certificate as part of the TLS connection: While HTTPS provides a means for client certificates, I find this to be more complicated than necessary.

  3. Time-of-day with encryption: Create yourself a separate RSA private and public key. Store the public key on the Client, and the Server will use the Private key to decrypt. The client will encrypt the time of day, and the server will verify that it is correct. (within range)

  4. Challenge-response: In this case, a Public RSA key is stored on the Server, and Private Key on the client. The server sends a random string to the client, along with a request id, and the client must be able to decrypt the info and send it back with the matching request id. If decryption was successful, then Client identity is verified.

    The benefit this has over the others is that, supposing, an attacker successfully hacks your server and downloads files, he will not be able to impersonate a Client without a more advanced hack. (though he would be a step closer to MITM) With solutions 1, 2 and 3, simply downloading the appropriate files from the server filesystem would provide the necessary info to impersonate a Client.

Solutions 3 and 4 would are best accompanied with a protection against Replay Attacks. Solution 1 is not compatible with Replay attack prevention. However, in your use case, using HTTPS, I think Replays are only an issue after a successful hack of the Server filesystem thereby permitting MITM.

Bonus:

  • IP Address: If possible, have the Server verify that the connection originates from a pre-determined Client IP address. If the Client IP address is verified not to change, this Bonus protection will provide a great deal of protection against any attacks on the above solutions I have provided.