Skip to content
Chrono edited this page Sep 14, 2021 · 3 revisions

This section will be describing how one can login using a registered account with the server.

API Root URL: https://mrchewitsoftware.com.my:5001/api/Login

Prerequisites:

  1. You must know how to convert data into/from Base64 encoding
  2. You must know how to convert data into URL encoded format
  3. You must know how to read cryptography data that stores on your side through files in binary format/any other applicable format
  4. You must know how to use query string in HttpGet
  5. You must know how to convert data into/from JSON string
https://mrchewitsoftware.com.my:5001/api/Login
https://mrchewitsoftware.com.my:5001/api/Login/VerifiySignatureBy?

These 2 different endpoint acts differently and have different purposes.

1st Endpoint: Requesting Server Signed Challenge

https://mrchewitsoftware.com.my:5001/api/Login

This endpoint was responsible for generating a signed random challenge

Here's an example on how to do it

Byte[] ServerRandomChallenge = new Byte[] { };
Byte[] ServerSignedRandomChallenge = new Byte[] { };
Byte[] ServerED25519PK = new Byte[] { };
Boolean ServerOnlineChecker = true;
Boolean CheckServerED25519PK = true;
Boolean Re_RequestRandomChallengeBoolean = true;
LoginModels MyLoginModels = new LoginModels();
if (ETLSSessionIDStorage.ETLSID.CompareTo("") != 0 && ETLSSessionIDStorage.ETLSID != null)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        var response = client.GetAsync("Login/");
        try
        {
            response.Wait();
        }
        catch
        {
            ServerOnlineChecker = false;
        }
        if (ServerOnlineChecker == true)
        {
            var result = response.Result;
            if (result.IsSuccessStatusCode)
            {
                var readTask = result.Content.ReadAsStringAsync();
                readTask.Wait();

                var LoginModelsResult = readTask.Result;
                MyLoginModels = JsonConvert.DeserializeObject<LoginModels>(LoginModelsResult);
                if (MyLoginModels.RequestStatus.Contains("Error"))
                {
                    //Display Error
                }
                else
                {
                    ServerSignedRandomChallenge = Convert.FromBase64String(MyLoginModels.SignedRandomChallengeBase64String);
                    ServerED25519PK = Convert.FromBase64String(MyLoginModels.ServerECDSAPKBase64String);
                    try
                    {
                        ServerRandomChallenge = SodiumPublicKeyAuth.Verify(ServerSignedRandomChallenge, ServerED25519PK);
                    }
                    catch
                    {
                        CheckServerED25519PK = false;
                    }
                    if (CheckServerED25519PK == true)
                    {
                        //Do something to display/store the verified server random challenge
                    }
                    else
                    {
                        //Display error and developer required to request the challenge again
                    }
                }
            }
            else
            {
                //Display error..
            }
        }
        else
        {
            //Server's offline
        }
    }
}
else
{
    //Developer requires to establish an ephemeral TLS session with the server
}

2nd Endpoint: Verifying user signed random challenge

https://mrchewitsoftware.com.my:5001/api/Login/VerifiySignatureBy?

This endpoint was responsible for verifying user signed random challenge

Here's an example on how to do it

String UserID = "";
Byte[] ServerRandomChallenge = new Byte[] { };
Byte[] UserSignedRandomChallenge = new Byte[] { };
Byte[] ETLSSignedUserSignedRandomChallenge = new Byte[] { };
Byte[] UserIDByte = new Byte[] { };
Byte[] ETLSSignedUserIDByte = new Byte[] { };
Byte[] ClientECDSASK = new Byte[] { };
Byte[] LoginECDSASK = new Byte[] { };
String LoginPath = Application.StartupPath + "\\Application_Data\\User\\";
String VerifyStatus = "";
Boolean ServerOnlineChecker = true;
if (ETLSSessionIDStorage.ETLSID.CompareTo("") != 0 && ETLSSessionIDStorage.ETLSID != null)
{
    if (CurrentUserIDTB.Text.CompareTo("") != 0 && CurrentUserIDTB.Text != null && ChallengeBase64TB.Text.CompareTo("") != 0 && ChallengeBase64TB.Text != null)
    {
        UserID = CurrentUserIDTB.Text;
        UserIDByte = Encoding.UTF8.GetBytes(UserID);
        //Get the verified random challenge and assign to this variable
        ServerRandomChallenge = Convert.FromBase64String(ChallengeBase64TB.Text);
        LoginPath += UserID;
        LoginPath += "\\" + "Authentication_Data" + "\\" + "Login" + "\\" + "LoginSK.txt";
        LoginECDSASK = File.ReadAllBytes(LoginPath);
        UserSignedRandomChallenge = SodiumPublicKeyAuth.Sign(ServerRandomChallenge, LoginECDSASK,true);
        ClientECDSASK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionIDStorage.ETLSID + "\\" + "ECDSASK.txt");
        ETLSSignedUserIDByte = SodiumPublicKeyAuth.Sign(UserIDByte, ClientECDSASK);
        ETLSSignedUserSignedRandomChallenge = SodiumPublicKeyAuth.Sign(UserSignedRandomChallenge, ClientECDSASK,true);
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            var response = client.GetAsync("Login/VerifySignatureBy?ClientPathID=" + ETLSSessionIDStorage.ETLSID + "&SignedUserID=" + 
                           HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserIDByte)) + "&SignedSignedRandomChallenge=" + 
                           HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserSignedRandomChallenge)));
            try
            {
                response.Wait();
            }
            catch
            {
                ServerOnlineChecker = false;
            }
            if (ServerOnlineChecker == true)
            {
                var result = response.Result;
                if (result.IsSuccessStatusCode)
                {
                    var readTask = result.Content.ReadAsStringAsync();
                    readTask.Wait();

                    VerifyStatus = readTask.Result;
                    if (VerifyStatus.Contains("Error"))
                    {
                        //Display Error
                    }
                    else
                    {
                        //Do something..
                    }
                }
                else
                {
                    //Display Error
                }
            }
            else
            {
                //Server's not online
            }
        }
    }
    else
    {
        //User must choose an user ID
    }
}
else
{
   //Developer must establish an ETLS session with the server
}

Clone this wiki locally