From 699e03fa51e9ae7e1dd3122fc45b6fd6e374c276 Mon Sep 17 00:00:00 2001 From: Eugene Fox Date: Tue, 1 Jun 2021 17:43:03 +0300 Subject: [PATCH] Updated Configuration (markdown) --- Configuration.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/Configuration.md b/Configuration.md index ec0defc..b81ee6f 100644 --- a/Configuration.md +++ b/Configuration.md @@ -1,5 +1,104 @@ Since you probably have multiple users on your service or multiple services on your device, you need to handle configurations for all the cases you have + +For list of configuration properties please refer to [OTPConfiguration - API reference](https://github.com/XFox111/SimpleOTP/wiki/OTPConfiguration) ## Generate configuration +To generate new configuration for user, simply call `OTPConfiguration.GenerateConfiguration`. It will generate new secret key for the instance and apply recommended settings (see below) +```csharp +OTPConfiguration config = OTPConfiguration.GenerateConfiguration("My service name", "target_username@or_an_email.com"); +``` +Default configuration +- OTP algorithm: Time-based OTP +- Key length: 160 bit (20 characters) +- Hashing algorithm: HMAC-SHA-1 +- OTP length: 6 digits +- Period: 30 seconds + +To override some of settings in generated configurations, you can set them manually: +```csharp +OTPConfiguration config = OTPConfiguration.GenerateConfiguration("My service name", "target_username@or_an_email.com"); +config.Digits = 8; +config.Algorithm = Algorithm.SHA512; +config.Period = TimeSpan.FromSeconds(60); +// etc. +``` ## Load configuration +To load existing configuration, you can call `GetConfiguration(string, string, string)` to load configuration with default settings. If you do so, you need to store only information about these three values. +```csharp +OTPConfiguration config = OTPConfiguration.GenerateConfiguration("MYSECRETKEY", "My service name", "target_username@or_an_email.com"); +Console.WriteLine(config); +// OTPModel { Id = af2358b0-3f69-4dd7-9537-32c07d6663aa, Type = TOTP, IssuerLabel = My service name, AccountName = target_username@or_an_email.com, Secret = MYSECRETKEY, Issuer = My service name, Algorithm = SHA1, Digits = 6, Counter = 0, Period = 00:00:30 } +``` +Alternatively, you can load configuration from [OTP AUTH URI](https://github.com/google/google-authenticator/wiki/Key-Uri-Format). In this way, you need to store only array of URIs: +```csharp +string sample_config_uri = "otpauth://totp/FoxDev%20Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev%20Studio"; +OTPConfiguration config = OTPConfiguration.GetConfiguration(sample_config_uri); +// OTPConfiguration { Id = af2358b0-3f69-4dd7-9537-32c07d6663aa, Type = TOTP, IssuerLabel = FoxDev Studio, AccountName = eugene@xfox111.net, Secret = ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH, Issuer = FoxDev Studio, Algorithm = SHA1, Digits = 6, Counter = 0, Period = 00:00:30 } +``` +Or just fill in properties manually. Then you need to serialize and deserialize the whole object: +```csharp +OTPConfiguration config = new () +{ + Type = OTPType.TOTP, + IssuerLabel = "My service name", + AccountName = "target_username@or_an_email.com", + Secret = "MYSECRETKEY", // To generate new secret you can use SimpleOTP.Helpers.SecretGenerator.GenerateSecret() + Issuer = "My service name", + Algorithm = Algorithm.SHA1, + Digits = 6, + Period = TimeSpan.FromSeconds(30) +} +``` ## Store configuration -TODO \ No newline at end of file +You can store data in three different ways: +### 1. Store whole object instance in database (suitable for server side): +```csharp +OTPConfiguration config = dbContenxt.Configs.Find("af2358b0-3f69-4dd7-9537-32c07d6663aa"); +dbContext.Configs.Update(config); +dbContext.SaveChanges(); +``` +Data in database `Configs` table: +| Id (PRIMARY_KEY) | Type | IssuerLabel | AccountName | Secret | Issuer | Algorithm | Digits | Counter | Period | +| ---------------- | ---- | ----------- | ----------- | ------ | ------ | --------- | ------ | ------- | ------ | +| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | +| af2358b0-3f69-4dd7-9537-32c07d6663aa | 0 | FoxDev Studio | eugene@xfox111.net | ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH | FoxDev Studio | 0 | 6 | 0 | 00:30:00.000 | +| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | + +### 2. Store serialized object as string in storage (e.g. `Xamarin.Essentials.Preferences`) +```csharp +List list = JsonConvert.DeserializeObject>(Preferences.Get("configs", "[]"); // [] - Empty JSON array for fallback value +list.Add(config); +Preferences.Set("configs", JsonConvert.SerializeObject(list)); +``` +Storage content: +```json +[ + { + "Id": "af2358b0-3f69-4dd7-9537-32c07d6663aa", + "Type": 0, + "IssuerLabel": "FoxDev Studio", + "AccountName": "eugene@xfox111.net", + "Secret": "ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH", + "Issuer": "FoxDev Studio", + "Algorithm": 0, + "Digits": 6, + "Counter": 0, + "Period": "00:30:00" + } +] +``` + +### 3. Store OTP AUTH URIs: +```csharp +List list = JsonConvert.DeserializeObject(Preferences.Get("configs", "[]").Select(i => OTPConfiguration.GetConfiguration(i)).ToList(); +list.Add(config); +Preferences.Set("configs", JsonConvert.SerializeObject(list.Select(i => i.GetUri().AbsoluteUri).ToArray())); +``` +Storage content: +```json +[ + "otpauth://totp/FoxDev%20Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev%20Studio", + "otpauth://totp/Service1:eugene@xfox111.net?secret=ESQ4GRRWIAUUWVHWQHVTYRM2CWZC3NX2&issuer=Service1", + "otpauth://totp/Service2:eugene@xfox111.net?secret=NX24GRRWIAUESQVTYRM2CWZC3UWVHWQH&issuer=Service2", + "otpauth://totp/Service3:eugene@xfox111.net?secret=WZCESQVTYRM2C3NX24GRRWIAUUWVHWQH&issuer=Service3" +] +``` \ No newline at end of file