summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Enzmann <christoph.enzmann@confer.ch>2013-12-05 13:01:46 +0100
committerChristoph Enzmann <christoph.enzmann@confer.ch>2013-12-05 13:01:46 +0100
commit0795b5d4083d9ad2cd5dfbcb5c12277f350485b2 (patch)
tree1a1878b94fc39a96eb37af291eda1796fbb627a5
parentb52682a9b3216a7d966238e3c8ed6b4da3920313 (diff)
downloadTwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.zip
TwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.tar.gz
TwoStepsAuthenticator-0795b5d4083d9ad2cd5dfbcb5c12277f350485b2.tar.bz2
GenerateKey now static, Update README.md
-rw-r--r--README.md43
-rw-r--r--TwoStepsAuthenticator.TestApp/ViewModel.cs2
-rw-r--r--TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs2
-rw-r--r--TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs2
-rw-r--r--TwoStepsAuthenticator/Authenticator.cs4
5 files changed, 37 insertions, 16 deletions
diff --git a/README.md b/README.md
index db96b7f..d2425a1 100644
--- a/README.md
+++ b/README.md
@@ -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);