1
0
mirror of https://github.com/XFox111/SimpleOTP.git synced 2026-04-23 08:08:40 +03:00

Created Code generation/validation (markdown)

2021-05-30 16:45:47 +03:00
parent 612b9a5c3e
commit 41a65b2bd8
+69
@@ -0,0 +1,69 @@
# Code generation/validation
Here we will look at how to generate an OTP on client side and validate it on server side
## Code generation
### Time-based OTP
For TOTP it's quite simple: you load your OTP configuration from your storage (in this example it's `Xamarin.Essentials.Preferences`) and then generate a new OTP code with `OTPService`
```csharp
OTPConfiguration totpConfig = JsonConvert.DeserializeObject<OTPConfiguration>(Preferences.Get("myTotpConfig", ""));
OTPCode code = OTPService.GenerateCode(ref totpConfig);
Debug.WriteLine(code); // OTPasswordModel { Code = 350386, Expiring = 23-May-21 06:08:30 PM }
```
### HMAC-based OTP
For HOTPs it's important to update your configuration after code generation because it's based on a counter which should be incremented each time you generate a password:
```csharp
OTPConfiguration hotpConfig = JsonConvert.DeserializeObject<OTPConfiguration>(Preferences.Get("myHotpConfig", ""));
OTPCode code = OTPService.GenerateCode(ref hotpConfig);
Debug.WriteLine(code); // OTPasswordModel { Code = 350386, Expiring = null } // Since HOTP isn't time related, it doesn't have expiration time
Preferences.Set("myHotpConfig", JsonConvert.SerializeObject(hotpConfig)); // It's important to update configuration to prevent desynchronization with server
```
It's also recommended to not let user generate HOTP in one action. Make sure you've notified user that generating code for no reason can cause a desynchronization with the server, thus inability to log in
## Code validation
### Time-based OTP
Code validation is quite like what we do with code generation. In this example as storage location, we will use an `DatabaseContext` from ASP.NET since usually validation occurs on server side
```csharp
[HttpGet]
public IActionResult Get(int code, Guid id)
{
OTPConfiguration totpConfig = db.Configs.Find(id);
if (OTPService.ValidateTotp(code, totpConfig, TimeSpan.FromSeconds(30)))
return Ok();
else
return Forbidden();
}
```
`TimeSpan.FromSeconds(30)` here is tolerance time which defines a set of periods, thus OTP codes which are valid at that moment. This is used to handle time desynchronization between server and client. If `OTPConfiguration.Period` is equal to 30 seconds, this tolerance time suggests that at that moment there're 3 valid OTP codes: current one, previous one and next one:
```
t - 30 t t + 30
| | |
| (n - 1)-th period | n-th period | (n + 1)-th period |
```
Recommended tolerance time: 30 seconds
### HMAC-based OTP
Similar to code generation, after code validation you need to update configuration in your storage. Note that HOTP counter increments only on successful validation
```csharp
[HttpGet]
public IActionResult Get(int code, Guid id)
{
OTPConfiguration hotpConfig = db.Configs.Find(id);
if (OTPService.ValidateHotp(code, ref hotpConfig, 1, true)) // 1 - toleranceSpan; true - resyncCounter
{
db.Update(hotpConfig);
db.SaveChanges();
return Ok();
}
else
return Forbidden();
}
```
For HOTP configuration tolerance span is presented in number of preceding and subsequent counters which should be treated as valid. Last parameter is `resyncCounter` and determines if `OTPService.ValidateHotp` should update counter according to provided OTP code
Recommended tolerance span: 1-2
It is also recommended to dismiss validated code to prevent from using it second time