diff options
author | Guillaume Lacasa <guillaume.lacasa@ucaya.com> | 2013-06-14 09:23:57 +0200 |
---|---|---|
committer | Guillaume Lacasa <guillaume.lacasa@ucaya.com> | 2013-06-14 09:23:57 +0200 |
commit | 0b4e94d02397bf6dd03c053610873dbdf8535059 (patch) | |
tree | 11e463b4787e01ec4daf22ba201e5ae9a02ad1d8 | |
parent | 8a0e9f0802038c80a4fc36cafbd97d9579795d09 (diff) | |
parent | db2840622d085b1920a370f3452c9bd323a36414 (diff) | |
download | TwoStepsAuthenticator-0b4e94d02397bf6dd03c053610873dbdf8535059.zip TwoStepsAuthenticator-0b4e94d02397bf6dd03c053610873dbdf8535059.tar.gz TwoStepsAuthenticator-0b4e94d02397bf6dd03c053610873dbdf8535059.tar.bz2 |
Merge branch 'master' of https://github.com/glacasa/TwoStepsAuthenticator
-rw-r--r-- | README.md | 26 | ||||
-rw-r--r-- | TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs | 1 | ||||
-rw-r--r-- | TwoStepsAuthenticator.TestApp/ViewModel.cs | 5 | ||||
-rw-r--r-- | TwoStepsAuthenticator/Authenticator.cs | 15 | ||||
-rw-r--r-- | TwoStepsAuthenticator/UsedCodesManager.cs | 4 |
5 files changed, 42 insertions, 9 deletions
@@ -1,6 +1,30 @@ TwoStepsAuthenticator ===================== -.net implementation of the TOTP: Time-Based One-Time Password Algorithm - RFC 6238 http://tools.ietf.org/html/rfc6238 +.net implementation of the TOTP: Time-Based One-Time Password Algorithm<br/> +RFC 6238 http://tools.ietf.org/html/rfc6238 compatible with Microsoft Authenticator for Windows Phone, and Google Authenticator for Android and iPhone. + +You can use this library as well for a client application (if you want to create your own authenticator) or for a server application (add two-step authentication on your asp.net website) + +For a client application, you need to save the secret key for your user. <br/> +Then, you only have to call the method GetCode(string) : + +<pre><code>var secret = user.secretAuthToken; +var authenticator = new TwoStepsAuthenticator.Authenticator(); +var code = authenticator.GetCode(secret);</code></pre> + +On a server application, you will have to generate a secret key, and share it with the user, who will have to enter it in his own authenticator app. + +<pre><code>var authenticator = new TwoStepsAuthenticator.Authenticator(); +var key = authenticator.GenerateKey();</code></pre> + +When the user will login, he will have to give you the code generated by his authenticator.<br/> +You can check if the code is correct with the method CheckCode(string secret, string code).<br/> +If the code is incorrect, don't log him. + +<pre><code>var secret = user.secretAuthToken; +var code = Request.Form["code"]; +var authenticator = new TwoStepsAuthenticator.Authenticator(); +var isok = authenticator.CheckCode(secret, code);</code></pre> diff --git a/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs b/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs index 43469af..f74a031 100644 --- a/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs +++ b/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs @@ -25,7 +25,6 @@ namespace TwoStepsAuthenticatorTestApp { InitializeComponent(); model = new ViewModel(); - model.Key="JBSWY3DPEHPK3PXP"; this.DataContext = model; } diff --git a/TwoStepsAuthenticator.TestApp/ViewModel.cs b/TwoStepsAuthenticator.TestApp/ViewModel.cs index 51db3a8..8bfeb9b 100644 --- a/TwoStepsAuthenticator.TestApp/ViewModel.cs +++ b/TwoStepsAuthenticator.TestApp/ViewModel.cs @@ -72,8 +72,9 @@ namespace TwoStepsAuthenticatorTestApp public ViewModel() { + var authenticator = new TwoStepsAuthenticator.Authenticator(); + this.Key = authenticator.GenerateKey(); timer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, timerCallback, App.Current.Dispatcher); - //timer.Elapsed += timer_Elapsed; timer.Start(); } @@ -96,6 +97,8 @@ namespace TwoStepsAuthenticatorTestApp { var auth = new TwoStepsAuthenticator.Authenticator(); Code = auth.GetCode(this.Key); + + auth.CheckCode(key, Code); } } } diff --git a/TwoStepsAuthenticator/Authenticator.cs b/TwoStepsAuthenticator/Authenticator.cs index d196525..0f0e298 100644 --- a/TwoStepsAuthenticator/Authenticator.cs +++ b/TwoStepsAuthenticator/Authenticator.cs @@ -9,11 +9,18 @@ namespace TwoStepsAuthenticator { public class Authenticator { - private static UsedCodesManager usedCodes = new UsedCodesManager(); + private static Lazy<UsedCodesManager> usedCodes = new Lazy<UsedCodesManager>(); public string GenerateKey() { - throw new NotImplementedException(); + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + var random = new Random(); + var keyChars = new char[16]; + for (int i = 0; i < 16; i++) + { + keyChars[i] = chars[random.Next(chars.Length)]; + } + return new String(keyChars); } public string GetCode(string secret) @@ -61,7 +68,7 @@ namespace TwoStepsAuthenticator public bool CheckCode(string secret, string code) { - if (usedCodes.IsCodeUsed(secret, code)) + if (usedCodes.Value.IsCodeUsed(secret, code)) return false; var baseTime = DateTime.Now; @@ -70,7 +77,7 @@ namespace TwoStepsAuthenticator var checkTime = baseTime.AddSeconds(30 * i); if (GetCode(secret, checkTime) == code) { - usedCodes.AddCode(secret, code); + usedCodes.Value.AddCode(secret, code); return true; } } diff --git a/TwoStepsAuthenticator/UsedCodesManager.cs b/TwoStepsAuthenticator/UsedCodesManager.cs index d60e1cb..3d4247b 100644 --- a/TwoStepsAuthenticator/UsedCodesManager.cs +++ b/TwoStepsAuthenticator/UsedCodesManager.cs @@ -41,14 +41,14 @@ namespace TwoStepsAuthenticator public UsedCodesManager() { codes = new Queue<UsedCode>(); - cleaner = new Timer(TimeSpan.FromSeconds(5).TotalMilliseconds); + cleaner = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds); cleaner.Elapsed += cleaner_Elapsed; cleaner.Start(); } void cleaner_Elapsed(object sender, ElapsedEventArgs e) { - var timeToClean = DateTime.Now.AddSeconds(-5); + var timeToClean = DateTime.Now.AddMinutes(-5); lock (codeLock) { while (codes.Count > 0 && codes.Peek().UseDate < timeToClean) |