I'm developing a REST API but I am unable to use HTTPS without using self-signed certificates. The information being passed on the network is not sensitive, so I don't care about eavesdropping, but I want to make sure that only authorized clients are able to make requests and prevent replay attacks. Here's my idea: A user is registered with the web application running the service. They want to register an API client, but they are not a developer, so they download a supplied client application (in this instance, an IC Card reader they will use with a computer that can communicate data read from the scanned cards to the web service over the API). The API client application generates a key pair (e.g. OpenSSL) and sends the public key to the server (this can be a manual upload step when the user registers the client with the server). The server stores the public key in the database associated with the user and a description of the client (e.g. “IC Card Reader on PC01”). When making a request the client first gets a nonce from the server (which stores it in a list or database of nonces and issued timestamps) and then makes the request including the nonce while signing the request with their private key. The server verifies that the message is authentic (was signed by the client and no one else) before executing the request. My goal with this approach is to ensure that only valid clients are accessing the API, while also preventing replay attacks. An attacker should be able to see the contents of the messages (not really sensitive), but should be unable to modify them. Does this approach meet these design goals? And does it prevent against man-in-the-middle attacks (assuming the original registration of the client was with the real server and not an attacker's fake one)?