diff options
author | Christoph Enzmann <christoph.enzmann@confer.ch> | 2013-12-05 13:01:46 +0100 |
---|---|---|
committer | Christoph Enzmann <christoph.enzmann@confer.ch> | 2013-12-05 13:01:46 +0100 |
commit | 0795b5d4083d9ad2cd5dfbcb5c12277f350485b2 (patch) | |
tree | 1a1878b94fc39a96eb37af291eda1796fbb627a5 | |
parent | b52682a9b3216a7d966238e3c8ed6b4da3920313 (diff) | |
download | TwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.zip TwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.tar.gz TwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.tar.bz2 |
GenerateKey now static, Update README.md
-rw-r--r-- | README.md | 43 | ||||
-rw-r--r-- | TwoStepsAuthenticator.TestApp/ViewModel.cs | 2 | ||||
-rw-r--r-- | TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs | 2 | ||||
-rw-r--r-- | TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs | 2 | ||||
-rw-r--r-- | TwoStepsAuthenticator/Authenticator.cs | 4 |
5 files changed, 37 insertions, 16 deletions
@@ -1,30 +1,51 @@ TwoStepsAuthenticator ===================== -.net implementation of the TOTP: Time-Based One-Time Password Algorithm<br/> -RFC 6238 http://tools.ietf.org/html/rfc6238 +.net implementation of the TOTP: Time-Based One-Time Password Algorithm and HOPT: HMAC-Based One-Time Password Algorithm<br/> +RFC 6238 http://tools.ietf.org/html/rfc6238<br> +RFC 4226 http://tools.ietf.org/html/rfc4226 -compatible with Microsoft Authenticator for Windows Phone, and Google Authenticator for Android and iPhone. +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> +<pre><code> +var secret = user.secretAuthToken; +var authenticator = new TwoStepsAuthenticator.TimeAuthenticator(); +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> +<pre><code> +var key = TwoStepsAuthenticator.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; +<pre><code> +var secret = user.secretAuthToken; var code = Request.Form["code"]; -var authenticator = new TwoStepsAuthenticator.Authenticator(); -var isok = authenticator.CheckCode(secret, code);</code></pre> +var authenticator = new TwoStepsAuthenticator.TimeAuthenticator(); +bool isok = authenticator.CheckCode(secret, code); +</code></pre> + +Every code should only be used once. To prevent repeated use of a code a UsedCodesManager class is provided.<br> +It should be used as a singleton instance. + +<pre><code> +var usedCodesManager = new UsedCodesManager(); +var secret = user.secretAuthToken; +var code = Request.Form["code"]; +if (autenticator.CheckCode(secret, code) && usedCodesManager.IsCodeUsed(secret, code)) { + usedCodesManager.AddCode(secret, code); + // OK +} else { + // Not OK +} +</code></pre>
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestApp/ViewModel.cs b/TwoStepsAuthenticator.TestApp/ViewModel.cs index 5a2e7b6..adc07a4 100644 --- a/TwoStepsAuthenticator.TestApp/ViewModel.cs +++ b/TwoStepsAuthenticator.TestApp/ViewModel.cs @@ -73,7 +73,7 @@ namespace TwoStepsAuthenticatorTestApp public ViewModel() { var authenticator = new TwoStepsAuthenticator.TimeAuthenticator(); - this.Key = authenticator.GenerateKey(); + this.Key = TwoStepsAuthenticator.Authenticator.GenerateKey(); timer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, timerCallback, App.Current.Dispatcher); timer.Start(); } diff --git a/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs b/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs index ebe7493..4738ba1 100644 --- a/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs +++ b/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs @@ -13,7 +13,7 @@ namespace TwoStepsAuthenticator.UnitTests { [Test] public void CreateKey() { var authenticator = new CounterAuthenticator(); - var secret = authenticator.GenerateKey(); + var secret = Authenticator.GenerateKey(); var code = authenticator.GetCode(secret, 0L); Assert.IsTrue(authenticator.CheckCode(secret, code, 0L), "Generated Code doesn't verify"); diff --git a/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs b/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs index 1f8c9ab..3d19ea2 100644 --- a/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs +++ b/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs @@ -12,7 +12,7 @@ namespace TwoStepsAuthenticator.UnitTests { [Test] public void CreateKey() { var authenticator = new TimeAuthenticator(); - var secret = authenticator.GenerateKey(); + var secret = Authenticator.GenerateKey(); var code = authenticator.GetCode(secret); Assert.IsTrue(authenticator.CheckCode(secret, code), "Generated Code doesn't verify"); diff --git a/TwoStepsAuthenticator/Authenticator.cs b/TwoStepsAuthenticator/Authenticator.cs index bee9b8b..81dc020 100644 --- a/TwoStepsAuthenticator/Authenticator.cs +++ b/TwoStepsAuthenticator/Authenticator.cs @@ -13,7 +13,7 @@ namespace TwoStepsAuthenticator private static readonly int KeyLength = 16; private static readonly string AvailableKeyChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; - public string GenerateKey() { + public static string GenerateKey() { var keyChars = new char[KeyLength]; for (int i = 0; i < keyChars.Length; i++) { keyChars[i] = AvailableKeyChars[RandomInt(AvailableKeyChars.Length)]; @@ -62,7 +62,7 @@ namespace TwoStepsAuthenticator return diff == 0; } - protected int RandomInt(int max) { + protected static int RandomInt(int max) { var randomBytes = new byte[4]; Random.GetBytes(randomBytes); |