-
Notifications
You must be signed in to change notification settings - Fork 1
ETLS_Operations
This section will be describing on all the possible ephemeral TLS(Transport Layer Security) operations with the server.
API Root URL: https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession
Prerequisites:
- You must know how to convert data into/from Base64 encoding
- You must know how to convert data into URL encoded format
- You must know how to generate a random password without special characters as an ASCII ID (will be useful later)
- You must know how to use query string in HttpGet
- You must know how to convert data into/from JSON string
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/byID?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/ByHandshake?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/BySharedSecret?
These 4 different endpoint acts differently and have different purposes.
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/byID?
This endpoint was responsible for initiating an ETLS session with the server.
Here's an example on how to do it.
public void InitializeNewSession()
{
//refers to the SecureIDGenerator in Helper
String MySession_ID = MySecureIDGenerator.GenerateUniqueString();
ECDH_ECDSA_Models MyECDH_ECDSA_Models = new ECDH_ECDSA_Models();
Boolean CheckServerOnline = true;
Boolean CreateShareSecretStatus = true;
Boolean CheckSharedSecretStatus = true;
Byte[] ServerECDSAPKByte = new Byte[] { };
Byte[] ServerECDHSPKByte = new Byte[] { };
Byte[] ServerECDHPKByte = new Byte[] { };
Boolean VerifyBoolean = true;
String SessionStatus = "";
String ExceptionString = "";
using (var InitializeHandShakeHttpclient = new HttpClient())
{
InitializeHandShakeHttpclient.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
InitializeHandShakeHttpclient.DefaultRequestHeaders.Accept.Clear();
InitializeHandShakeHttpclient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = InitializeHandShakeHttpclient.GetAsync("ECDH_ECDSA_TempSession/byID?ClientPathID=" + MySession_ID);
try
{
response.Wait();
}
catch
{
CheckServerOnline = false;
}
if (CheckServerOnline == true)
{
var result = response.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsStringAsync();
readTask.Wait();
var ECDH_ECDSA_Models_Result = readTask.Result;
MyECDH_ECDSA_Models = JsonConvert.DeserializeObject<ECDH_ECDSA_Models>(ECDH_ECDSA_Models_Result);
if (MyECDH_ECDSA_Models.ID_Checker_Message.CompareTo("You still can use the exact same client ID...") == 0 || MyECDH_ECDSA_Models.ID_Checker_Message.CompareTo("You have an exact client ID great~") == 0)
{
ServerECDSAPKByte = Convert.FromBase64String(MyECDH_ECDSA_Models.ECDSA_PK_Base64String);
ServerECDHSPKByte = Convert.FromBase64String(MyECDH_ECDSA_Models.ECDH_SPK_Base64String);
try
{
ServerECDHPKByte = SodiumPublicKeyAuth.Verify(ServerECDHSPKByte, ServerECDSAPKByte);
}
catch (Exception exception)
{
VerifyBoolean = false;
ExceptionString = exception.ToString();
SessionStatus += ExceptionString + Environment.NewLine;
}
if (VerifyBoolean == true)
{
//Do something here... as the system able to verify the server signed ECDHPK or X25519PK
//Please store the verified server ECDHPK or X25519 PK as it will be useful later
}
else
{
//Do something here as the system unable to verify the server signed ECDHPK or X25519PK
}
//These might not be necessary but I leave it there for clearing the server public key material on the client
//side through cryptography secure way
SodiumSecureMemory.SecureClearBytes(ServerECDSAPKByte);
SodiumSecureMemory.SecureClearBytes(ServerECDHSPKByte);
SodiumSecureMemory.SecureClearBytes(ServerECDHPKByte);
SodiumSecureMemory.SecureClearString(MyECDH_ECDSA_Models.ECDSA_PK_Base64String);
SodiumSecureMemory.SecureClearString(MyECDH_ECDSA_Models.ECDH_SPK_Base64String);
}
else
{
//Do something..
}
}
else
{
//Do something..
}
}
else
{
//Do something..
}
}
}
There's a reason why there's a need to use cryptography random number generator to generate random ASCII ID. This was done with a reason that it can avoid possible ID duplication in the server side.
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?
This endpoint is responsible for deleting ETLS session
Here's an example on how to do it
Boolean ServerOnlineChecker = true;
StreamReader MyStreamReader = new StreamReader(Application.StartupPath + "\\Temp_Session\\" + "SessionID.txt");
String Temp_Session_ID = MyStreamReader.ReadLine();
MyStreamReader.Close();
Byte[] ClientECDSASKByte = new Byte[] { };
Byte[] RandomData = new Byte[240];
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
rngCsp.GetBytes(RandomData);
Byte[] SignedRandomData = new Byte[] { };
String Status = "";
if (Temp_Session_ID != null && Temp_Session_ID.CompareTo("") != 0)
{
using (var client = new HttpClient())
{
ClientECDSASKByte = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + Temp_Session_ID + "\\ECDSASK.txt");
SignedRandomData = SodiumPublicKeyAuth.Sign(RandomData, ClientECDSASKByte,true);
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("ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?ClientPathID=" + Temp_Session_ID + "&ValidationData=" + HttpUtility.UrlEncode(Convert.ToBase64String(SignedRandomData)));
SodiumSecureMemory.SecureClearBytes(RandomData);
SodiumSecureMemory.SecureClearBytes(SignedRandomData);
try
{
response.Wait();
}
catch
{
ServerOnlineChecker = false;
}
if (ServerOnlineChecker == true)
{
var result = response.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsStringAsync();
readTask.Wait();
Status = readTask.Result;
if (Status.Contains("Error"))
{
//Do something
}
else
{
//Do something..
}
}
else
{
//Do something..
}
}
}
}
else
{
//Do something..
}
Warning: This function can only be call if you had established a working ephemeral TLS session with the server.
In future, this endpoint will work differently as it's still a work in the progress at the moment.. For the time being, this is how you can call it
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/ByHandshake?
This endpoint is responsible for establishing ETLS session
Here's an example on how to do it
//The MySession_ID is the ASCII ID that was sent to the server during ETLS initialization
//SignedClientSessionECDHPKByte is the client's signed X25519 PK or ECDHPK
//ClientSessionECDSAPKByte is the client's ED25519 PK or ECDSA PK
public void CreateSharedSecret(ref Boolean CheckBoolean, String MySession_ID, Byte[] SignedClientSessionECDHPKByte, Byte[] ClientSessionECDSAPKByte)
{
CheckBoolean = false;
String SessionStatus = "";
var CreateSharedSecretHttpClient = new HttpClient();
CreateSharedSecretHttpClient.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
CreateSharedSecretHttpClient.DefaultRequestHeaders.Accept.Clear();
CreateSharedSecretHttpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var newresponse = CreateSharedSecretHttpClient.GetAsync("ECDH_ECDSA_TempSession/ByHandshake?ClientPathID=" + MySession_ID + "&SECDHPK=" +
HttpUtility.UrlEncode(Convert.ToBase64String(SignedClientSessionECDHPKByte)) + "&ECDSAPK=" +
HttpUtility.UrlEncode(Convert.ToBase64String(ClientSessionECDSAPKByte)));
try
{
newresponse.Wait();
var newresult = newresponse.Result;
if (newresult.IsSuccessStatusCode)
{
var newreadTask = newresult.Content.ReadAsStringAsync();
newreadTask.Wait();
SessionStatus += newreadTask.Result;
if (SessionStatus.Contains("Error")==true)
{
CheckBoolean = false;
}
else
{
CheckBoolean = true;
}
}
else
{
//Do something..
}
}
catch
{
//Do something..
}
}
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/BySharedSecret?
This endpoint is responsible for checking shared secret
Here's an example on how to do it
public void CheckSharedSecret(ref Boolean CheckBoolean, String MySession_ID, Byte[] ServerECDHPKByte, Byte[] SessionECDHPrivateKey, Byte[] SessionECDSAPrivateKey)
{
CheckBoolean = false;
Boolean CheckServerOnline = true;
String CheckSharedSecretStatus = "";
Byte[] TestData = new Byte[] { 255, 255, 255 };
Byte[] SharedSecretByte = SodiumScalarMult.Mult(SessionECDHPrivateKey, ServerECDHPKByte,true);
Byte[] NonceByte = SodiumSecretBox.GenerateNonce();
Byte[] TestEncryptedData = SodiumSecretBox.Create(TestData, NonceByte, SharedSecretByte);
var CheckSharedSecretHttpClient = new HttpClient();
CheckSharedSecretHttpClient.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
CheckSharedSecretHttpClient.DefaultRequestHeaders.Accept.Clear();
CheckSharedSecretHttpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var CheckSharedSecretHttpClientResponse = CheckSharedSecretHttpClient.GetAsync("ECDH_ECDSA_TempSession/BySharedSecret?ClientPathID=" + MySession_ID + "&CipheredData=" + HttpUtility.UrlEncode(Convert.ToBase64String(TestEncryptedData)) + "&Nonce=" + HttpUtility.UrlEncode(Convert.ToBase64String(NonceByte)));
try
{
CheckSharedSecretHttpClientResponse.Wait();
}
catch
{
CheckServerOnline = false;
}
if (CheckServerOnline == true)
{
var CheckSharedSecretHttpClientResponseResult = CheckSharedSecretHttpClientResponse.Result;
if (CheckSharedSecretHttpClientResponseResult.IsSuccessStatusCode)
{
var CheckSharedSecretHttpClientResponseResultReadTask = CheckSharedSecretHttpClientResponseResult.Content.ReadAsStringAsync();
CheckSharedSecretHttpClientResponseResultReadTask.Wait();
CheckSharedSecretStatus = CheckSharedSecretHttpClientResponseResultReadTask.Result;
if (CheckSharedSecretStatus.Contains("Error"))
{
CheckBoolean = false;
}
else
{
//Do something here..
//Make sure to store the ETLS session ID, Shared Secret and ED25519 SK or ECDSA SK
//These will be prerequisites to communicate with the server API
CheckBoolean = true;
}
}
else
{
//Do something here..
}
//Clearing shared secret securely from memory through cryptography functions.
SodiumSecureMemory.SecureClearBytes(SharedSecretByte);
}
else
{
//Do something here..
}
}