HTTP/S Pairing
Overview
Here we start with a question:
How can we securely authenticate an untrusted client over an insecure network? |
This involves quite a bit of cryptography and a few steps between the client (Moonlight) and the server (Wolf).
Phase 1
Moonlight will send a salt and client certificate, users will see a prompt asking to insert the password on the remote server. On the backend, we’ll need the PIN to be inserted by the user.
PIN and SALT will be used to derive a shared AES key that needs to be stored in order to be used to decrypt in the next phases.
At this stage we only have to send back our public certificate (plaincert
).
Phase 2
Using the AES key that we generated in the phase 1 we have to decrypt the client challenge,
We generate a SHA256 hash with the following:
-
Decrypted challenge
-
Server certificate signature
-
Server secret: a randomly generated secret
The hash + server_challenge will then be AES encrypted and sent as the challengeresponse
Phase 3
Moonlight will send back a serverchallengeresp
: an AES encrypted client hash, we have to send back the pairingsecret
:
using our private key we have to sign the certificate_signature + server_secret (generated in phase 2)
Phase 4
We now have to use everything we exchanged before in order to verify and finally pair the clients.
We’ll check the client_hash obtained at phase 3, it should contain the following:
-
The original server_challenge
-
The signature of the X509 client_cert
-
The unencrypted
client_pairing_secret
We’ll check that SHA256(server_challenge + client_public_cert_signature + client_secret) == client_hash
Then using the client certificate public key we should be able to verify that the client secret has been signed by Moonlight
The response will contain:
-
paired = 1, if all checks are fine
-
paired = 0, otherwise