-
Notifications
You must be signed in to change notification settings - Fork 1
Account Recovery
This section will be describing how developers can call account recovery related functions in this server API.
Warning: This is a conditional account recovery.. If the keys were lost, it's impossible to perform account recovery.
Warning: However, normal users don't need to worry about account recovery.. If there exists a corporate version, account
recovery will play a role
API Root URL: https://mrchewitsoftware.com.my:5001/api/AccountRecovery
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 read cryptography data that stores on your side through files in binary format/any other applicable format
- 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/AccountRecovery/byUserID?
https://mrchewitsoftware.com.my:5001/api/AccountRecovery/DeletebyUserID?
https://mrchewitsoftware.com.my:5001/api/AccountRecovery/UpdatebyUserID?
These 3 endpoints act differently and have different purposes
https://mrchewitsoftware.com.my:5001/api/AccountRecovery/byUserID?
This endpoint was responsible to request account recovery data from server.
Here's an example on how to do it.
public String GetRecoveryData(String UserID)
{
Byte[] UserIDByte = new Byte[] { };
Byte[] ETLSSignedUserIDByte = new Byte[] { };
Boolean ServerOnlineChecker = true;
String ETLSSessionID = "";
Byte[] ClientECDSASK = new Byte[] { };
ETLSSessionID = File.ReadAllText(Application.StartupPath + "\\Temp_Session\\" + "SessionID.txt");
if (ETLSSessionID != null && ETLSSessionID.CompareTo("") != 0)
{
ClientECDSASK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionID + "\\" + "ECDSASK.txt");
if (UserID != null && UserID.CompareTo("") != 0)
{
UserIDByte = Encoding.UTF8.GetBytes(UserID);
ETLSSignedUserIDByte = SodiumPublicKeyAuth.Sign(UserIDByte, 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("AccountRecovery/byUserID?ClientPathID=" + ETLSSessionID + "&SignedUserID=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserIDByte)));
try
{
response.Wait();
}
catch
{
ServerOnlineChecker = false;
}
if (ServerOnlineChecker == true)
{
var result = response.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsStringAsync();
readTask.Wait();
return readTask.Result;
}
else
{
return "Error: Failed to fetch value from server";
}
}
else
{
return "Error: Server is not online";
}
}
}
else
{
SodiumSecureMemory.SecureClearBytes(ClientECDSASK);
return "";
}
}
else
{
return "";
}
}
https://mrchewitsoftware.com.my:5001/api/AccountRecovery/DeletebyUserID?
This endpoint was responsible to delete account data from server.
Here's an example on how to do it.
public Boolean DeleteAccount(String UserID, Byte[] ED25519PK,Byte[] UserSymmetricKey)
{
Byte[] UserIDByte = new Byte[] { };
Byte[] ETLSSignedUserIDByte = new Byte[] { };
Byte[] ETLSSignedED25519PK = new Byte[] { };
Byte[] ServerECDHPK = new Byte[] { };
Byte[] SealedUserSymmetricKey = new Byte[] { };
Boolean ServerOnlineChecker = true;
String ETLSSessionID = "";
String Status = "";
Byte[] ClientECDSASK = new Byte[] { };
ETLSSessionID = File.ReadAllText(Application.StartupPath + "\\Temp_Session\\" + "SessionID.txt");
if (ETLSSessionID != null && ETLSSessionID.CompareTo("") != 0)
{
if (UserID != null && UserID.CompareTo("") != 0)
{
ClientECDSASK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionID + "\\" + "ECDSASK.txt");
//This is the server ECDHPK or X25519 PK that developer require to store on client device if client
//would like to have account recovery.
ServerECDHPK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionID + "\\ServerECDHPK.txt");
SealedUserSymmetricKey = SodiumSealedPublicKeyBox.Create(UserSymmetricKey,ServerECDHPK);
UserIDByte = Encoding.UTF8.GetBytes(UserID);
ETLSSignedUserIDByte = SodiumPublicKeyAuth.Sign(UserIDByte, ClientECDSASK);
ETLSSignedED25519PK = SodiumPublicKeyAuth.Sign(ED25519PK, 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("AccountRecovery/DeletebyUserID?ClientPathID=" + ETLSSessionID + "&SignedUserID=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserIDByte)) + "&SignedECDSAPK=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedED25519PK))+"&SealedUserSymmetricKey="+HttpUtility.UrlEncode(Convert.ToBase64String(SealedUserSymmetricKey)));
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"))
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
}
else
{
return false;
}
}
else
{
return false;
}
}
https://mrchewitsoftware.com.my:5001/api/AccountRecovery/UpdatebyUserID?
This endpoint was responsible to delete account data from server.
Here's an example on how to do it.
public Boolean ResetAccount(String UserID, Byte[] ED25519PK,Byte[] UserSymmetricKey)
{
Boolean ResetStatus = false;
String ETLSSessionID = "";
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
Byte[] UserIDByte = new Byte[] { };
Byte[] MyETLSSignedSecureUserIDByte = new Byte[] { };
Byte[] ServerECDHPK = new Byte[] { };
Byte[] SealedUserSymmetricKey = new Byte[] { };
Byte[] UserLoginED25519PK = new Byte[] { };
Byte[] UserLoginSignedED25519PK = new Byte[] { };
Byte[] ETLSSignedUserLoginED25519PK = new Byte[] { };
Byte[] ETLSSignedUserLoginSignedED25519PK = new Byte[] { };
Byte[] RandomData = new Byte[128];
Byte[] CipheredRandomData = new Byte[] { };
Byte[] NonceByte = new Byte[] { };
Byte[] CombinedCipheredRandomData = new Byte[] { };
Byte[] SignedCombinedCipheredRandomData = new Byte[] { };
Byte[] ETLSSignedSignedCombinedCipheredRandomData = new Byte[] { };
Byte[] StreamCipherKeyByte = new Byte[] { };
Byte[] ClientECDSASK = new Byte[] { };
Byte[] ETLSSignedED25519PK = new Byte[] { };
Boolean CheckServerBoolean = true;
RevampedKeyPair MyLoginKeyPair = SodiumPublicKeyAuth.GenerateRevampedKeyPair();
RevampedKeyPair MyRecoveryKeyPair = SodiumPublicKeyAuth.GenerateRevampedKeyPair();
String UserIDStoragePath = Application.StartupPath + "\\Application_Data\\User\\";
ETLSSessionID = File.ReadAllText(Application.StartupPath + "\\Temp_Session\\" + "SessionID.txt");
if (ETLSSessionID != null && ETLSSessionID.CompareTo("") != 0)
{
if (UserID == null || UserID.CompareTo("") == 0)
{
//Display Error
}
else
{
ClientECDSASK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionID + "\\" + "ECDSASK.txt");
ServerECDHPK = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + ETLSSessionID + "\\ServerECDHPK.txt");
SealedUserSymmetricKey = SodiumSealedPublicKeyBox.Create(UserSymmetricKey, ServerECDHPK);
UserIDByte = Encoding.UTF8.GetBytes(UserID);
UserLoginED25519PK = MyLoginKeyPair.PublicKey;
rngCsp.GetBytes(RandomData);
NonceByte = SodiumSecretBox.GenerateNonce();
StreamCipherKeyByte = SodiumSecretBox.GenerateKey();
CipheredRandomData = SodiumSecretBox.Create(RandomData, NonceByte, StreamCipherKeyByte);
CombinedCipheredRandomData = NonceByte.Concat(CipheredRandomData).ToArray();
SignedCombinedCipheredRandomData = SodiumPublicKeyAuth.Sign(CombinedCipheredRandomData, MyRecoveryKeyPair.PrivateKey);
MyETLSSignedSecureUserIDByte = SodiumPublicKeyAuth.Sign(UserIDByte, ClientECDSASK);
UserLoginSignedED25519PK = SodiumPublicKeyAuth.Sign(UserLoginED25519PK, MyLoginKeyPair.PrivateKey);
ETLSSignedUserLoginSignedED25519PK = SodiumPublicKeyAuth.Sign(UserLoginSignedED25519PK, ClientECDSASK);
ETLSSignedUserLoginED25519PK = SodiumPublicKeyAuth.Sign(UserLoginED25519PK, ClientECDSASK);
ETLSSignedSignedCombinedCipheredRandomData = SodiumPublicKeyAuth.Sign(SignedCombinedCipheredRandomData, ClientECDSASK);
ETLSSignedED25519PK = SodiumPublicKeyAuth.Sign(ED25519PK, 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("AccountRecovery/UpdatebyUserID?ClientPathID=" + ETLSSessionID + "&SignedUserID=" + HttpUtility.UrlEncode(Convert.ToBase64String(MyETLSSignedSecureUserIDByte)) + "&SignedECDSAPK=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedED25519PK)) + "&SignedLoginSignedPK=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserLoginSignedED25519PK)) + "&SignedLoginPK=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedUserLoginED25519PK)) + "&SignedCiphered_Recovery_Data=" + HttpUtility.UrlEncode(Convert.ToBase64String(ETLSSignedSignedCombinedCipheredRandomData)) + "&SealedUserSymmetricKey=" + HttpUtility.UrlEncode(Convert.ToBase64String(SealedUserSymmetricKey)));
try
{
response.Wait();
}
catch
{
CheckServerBoolean = false;
}
if (CheckServerBoolean == true)
{
var result = response.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsStringAsync();
readTask.Wait();
var Result = readTask.Result;
if (Result.Contains("Error"))
{
//Display Error
}
else
{
//Store Recovery ED25519 PK and SK
//Store Recovery Stream Cipher Key
//Store Signed Combined Ciphered Random Data(Optional)
SodiumSecureMemory.SecureClearBytes(StreamCipherKeyByte);
MyRecoveryKeyPair.Clear();
MyLoginKeyPair.Clear();
ResetStatus = true;
}
}
else
{
//Display Error
}
}
else
{
//Server is offline
}
}
}
}
else
{
//ETLS session must be established
MyRecoveryKeyPair.Clear();
MyLoginKeyPair.Clear();
}
return ResetStatus;
}