Skip to content
This repository has been archived by the owner on Jan 9, 2019. It is now read-only.

Understanding the Handshake

Joshua Garner edited this page Dec 28, 2016 · 2 revisions

The Ulterius server has multiple websocket endpoints to ensure data does not become congested:

  • api
  • screenshare
  • webcam
  • terminal

Aside from terminal (which has its own unique handshake process), the endpoints share an authentication state. Once one has been authenticated, the client can send messages to the other without the need to rehandshake.

The initial connection to the server should target the api endpoint, which is located at ws://127.0.0.1:22007/api by default. Upon connection a unique RSA key pair is generated and the public key is sent over as the following JSON:

{"endpoint":"connectedToUlterius","results":{"message":"Ulterius server online!","publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBb3dyMVZZR1pWZThGYWFrb3JmYzUNClV5djVMWW5IVTU4RDN0OGI3WStzRE96QUtkWkdQd3ROa2VRUTFFVW1uY0pNRlVYTXoxSk9RWHBZUnBCVWQ4akkNClFlUWkrQ1BjemxaWDZvMkNYUEJWQXVaMTFaRGlCcGk4bGQwSy9sVTQ5ZElBYXlvcG5zaXZaS0szMms4WVFMN1kNCnRwRWEzUUFmMmhUMDJGS0NjeXloKzRiZm5nN0RmeFJvZkxQZ3JKaGNYdjRueE9oL2pjbHJCZzVhYWhkcngxVUUNCnhqRkQ4VkUvM3Z3Zk5JM2lMdkpTN1FjK042VmlYZW1rU3hjM2c0T1ZUMTdjTEM3cnNHVGlWeFBDN0dVQ2p3UnINCjRkb0FGZk5HM1drVEJzQ0hNdm4yVVlNSXVTM0ViT0NJc2Q1ZFZncDYva21pYWF2S1hGSTNjR2hESklMdFJFWCsNCitRSURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0NCg=="}}

This public key will be used to encrypt the AES credentials the server will use to encrypt connection traffic.

You'll need to generate an AES key and IV, a JS example of which can be seen here:

function generateHexString(length: number) {
    let ret = ""
    while (ret.length < length) {
        ret += Math.random().toString(16).substring(2)
    }
    return ret.substring(0, length)
}
 let key = generateHexString(16)
 let iv = generateHexString(16)

Once generated, encrypt the keys using the public key that was sent, then send a message body to the server with the results. Here is an example:

{"endpoint":"aeshandshake","synckey":"normal1","args":["AmDk/RxzIq6NR8W5x5+Dn3kdSveb6+Ec39Aq0QK4Tg67ZDIO4r4gOZCmQ5++2+O74GT714cJvn2MTzjvYxj+NauW8KUQL8TcHuBB9bjqVFpBuGHnIofQsJK5uplVyFgiPyiT5c6e2/W89PmLwYHupUcsUXbuTN5jCtqFQECeeOe4uIBckFAPE/5YV729s1AvEHBg/ihmQQsAQ1pPAjEuc930e+yQmAJuOsRRfTW2BN47IGj34mO0MHjbIf4QJasMm/3bFNQj1uDqI81x7OtTtyVDTkZp4udOVc+sLLAFolRZhquCSJMsZfb40Et5spOc233tEXyo11OS6FsXJnISrw==","bev4Xv1bo7jyGg6S0WiVRj31VUzfjgV3Q31mk+2FQywjomYdoijP9RftRJrFgsFClmazp4vXf89RGV/PVSaO3sjalucQQRVt8iCKMPUL6xbHglcFuyi2IK9jb4lfn6Zepw2/z29Y6YXmQ91u9uludSM/1+Ps0kbkXz8LHG7M9Ig/LB/FoFZiYyiexu3gsOiqAdEGR09QvgtoUAB8JMhjZo4m/5Fh88Zh0psBHv3viN8zndKYoSf4pGog8abk37nwV0tGLJYzbzNIdYogtqAeJT0Ew0/IfldG81q+IG1yYR9B4iHIvvZ5lo8K5IT0kW/v+oIabS+ZLU2z8JeyvPkc5Q=="]}
  • The endpoint field is the name of the endpoint you wish to target, in this case "aeshandshake". A full list of possible endpoints can be found here.
  • The synckey field is optional and allows you to pair requests and responses. The response from the server will contain the sync key set during the request.
  • The args field allows you to put arguments for individual endpoints. Arguments should be placed in the correct order when being sent to the server. In this case, the first argument is the encrypted key while the second is the encrypted IV.

If your AES handshake is accepted, you'll receive an encrypted reply which should be decrypted using the AES credentials previously generated. Otherwise it will be a plain text JSON body stating there was an error.

Continue to Understanding the Packet Body to find how to handle replies.

Clone this wiki locally