summaryrefslogtreecommitdiffstats
path: root/TwoStepsAuthenticator.DotnetCore/Authenticator.cs
diff options
context:
space:
mode:
authorGuillaume Lacasa <guillaumelacasa@hotmail.com>2016-06-29 10:43:45 +0200
committerGuillaume Lacasa <guillaumelacasa@hotmail.com>2016-06-29 12:46:06 +0200
commit8e80d5923232b6b5852873a8c54fc3d8bbbc9a96 (patch)
tree05c8206b8e1aa94ec40b0e9cb921b2a3b06b3535 /TwoStepsAuthenticator.DotnetCore/Authenticator.cs
parent8cfb0a7876aa457254f199ca99210b58284e1151 (diff)
downloadTwoStepsAuthenticator-8e80d5923232b6b5852873a8c54fc3d8bbbc9a96.zip
TwoStepsAuthenticator-8e80d5923232b6b5852873a8c54fc3d8bbbc9a96.tar.gz
TwoStepsAuthenticator-8e80d5923232b6b5852873a8c54fc3d8bbbc9a96.tar.bz2
Dotnet Core support
Diffstat (limited to 'TwoStepsAuthenticator.DotnetCore/Authenticator.cs')
-rw-r--r--TwoStepsAuthenticator.DotnetCore/Authenticator.cs78
1 files changed, 78 insertions, 0 deletions
diff --git a/TwoStepsAuthenticator.DotnetCore/Authenticator.cs b/TwoStepsAuthenticator.DotnetCore/Authenticator.cs
new file mode 100644
index 0000000..95ce955
--- /dev/null
+++ b/TwoStepsAuthenticator.DotnetCore/Authenticator.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TwoStepsAuthenticator
+{
+ public abstract class Authenticator
+ {
+#if CORE
+ private static readonly RandomNumberGenerator Random = RandomNumberGenerator.Create();
+#else
+ private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
+#endif
+ private static readonly int KeyLength = 16;
+ private static readonly string AvailableKeyChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+
+ public static string GenerateKey() {
+ var keyChars = new char[KeyLength];
+ for (int i = 0; i < keyChars.Length; i++) {
+ keyChars[i] = AvailableKeyChars[RandomInt(AvailableKeyChars.Length)];
+ }
+ return new String(keyChars);
+ }
+
+ protected string GetCodeInternal(string secret, ulong challengeValue) {
+ ulong chlg = challengeValue;
+ byte[] challenge = new byte[8];
+ for (int j = 7; j >= 0; j--) {
+ challenge[j] = (byte)((int)chlg & 0xff);
+ chlg >>= 8;
+ }
+
+ var key = Base32Encoding.ToBytes(secret);
+ for (int i = secret.Length; i < key.Length; i++) {
+ key[i] = 0;
+ }
+
+ HMACSHA1 mac = new HMACSHA1(key);
+ var hash = mac.ComputeHash(challenge);
+
+ int offset = hash[hash.Length - 1] & 0xf;
+
+ int truncatedHash = 0;
+ for (int j = 0; j < 4; j++) {
+ truncatedHash <<= 8;
+ truncatedHash |= hash[offset + j];
+ }
+
+ truncatedHash &= 0x7FFFFFFF;
+ truncatedHash %= 1000000;
+
+ string code = truncatedHash.ToString();
+ return code.PadLeft(6, '0');
+ }
+
+ protected bool ConstantTimeEquals(string a, string b) {
+ uint diff = (uint)a.Length ^ (uint)b.Length;
+
+ for (int i = 0; i < a.Length && i < b.Length; i++) {
+ diff |= (uint)a[i] ^ (uint)b[i];
+ }
+
+ return diff == 0;
+ }
+
+ protected static int RandomInt(int max) {
+ var randomBytes = new byte[4];
+ Random.GetBytes(randomBytes);
+
+ return Math.Abs((int)BitConverter.ToUInt32(randomBytes, 0) % max);
+ }
+
+
+ }
+}