Пример #1
0
        public static int CalcOTP(string key, long time)
        {
            time /= 30;
            var keyData  = Base32StringToBytes(key);
            var timeData = BitConverter.GetBytes(time).Reverse().ToArray();

            var result = new HMACSHA1(keyData).ComputeHash(timeData);

            int i = (int)(result.Last() & 15);

            return(((int)(result[i] & 127) << 24 | (int)(result[i + 1] & 255) << 16 | (int)(result[i + 2] & 255) << 8 | (int)(result[i + 3] & 255)) % 1000000);
        }
Пример #2
0
        private void CalculateOneTimePassword()
        {
            // https://tools.ietf.org/html/rfc4226
            Timestamp = Convert.ToInt64(GetUnixTimestamp() / 30);
            var data = BitConverter.GetBytes(Timestamp).Reverse().ToArray();

            Hmac            = new HMACSHA1(Secret).ComputeHash(data);
            Offset          = Hmac.Last() & 0x0F;
            OneTimePassword = (
                ((Hmac[Offset + 0] & 0x7f) << 24) |
                ((Hmac[Offset + 1] & 0xff) << 16) |
                ((Hmac[Offset + 2] & 0xff) << 8) |
                (Hmac[Offset + 3] & 0xff)
                ) % 1000000;
        }
Пример #3
0
        private static string GenerateOtpCode(string otpSecret)
        {
            var timestamp       = Convert.ToInt64(Convert.ToInt64(Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds)) / 30);
            var data            = BitConverter.GetBytes(timestamp).Reverse().ToArray();
            var hmac            = new HMACSHA1(ToBytes(otpSecret)).ComputeHash(data);
            var offset          = hmac.Last() & 0x0F;
            var oneTimePassword = (
                ((hmac[offset + 0] & 0x7f) << 24) |
                ((hmac[offset + 1] & 0xff) << 16) |
                ((hmac[offset + 2] & 0xff) << 8) |
                (hmac[offset + 3] & 0xff)) % 1000000;

            var code = oneTimePassword.ToString().PadLeft(6, '0');

            return(code);
        }
Пример #4
0
        private string ComputeCode(string secret, long counter)
        {
            var buffer = Base32.Decode(secret);

            var hash = new HMACSHA1(buffer).ComputeHash(BitConverter.GetBytes(counter).Reverse().ToArray());

            var offset = hash.Last() & 0x0F;

            var truncatedHash = ((hash[offset] & 0x7f) << 24)
                                | (hash[offset + 1] << 16)
                                | (hash[offset + 2] << 8)
                                | hash[offset + 3];

            var code = (truncatedHash % 1000000).ToString().PadLeft(6, '0');

            return(code);
        }
Пример #5
0
        //-------------------------------------------------------------------------------------------------
        //--- Generate a OneTime Password from a Guid
        //-------------------------------------------------------------------------------------------------
        public static async Task <int> OTPFromGuid(Guid TheGuid, bool UseNetworkTime = false)
        {
            Int64 myTimeStamp;

            byte[] mySecret;
            byte[] myHmac;
            byte[] myData;
            int    myOffset;
            int    myOneTimePassword;
            Int64  MyUnixTimestamp;

            mySecret = StringToBytes(TheGuid.ToString("N"));

#if WINDOWS_UWP
            var myCryptprovider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1);
#else
            HMACSHA1 crypt = new HMACSHA1(mySecret);
#endif
            MyUnixTimestamp = await GetUnixTimestamp(UseNetworkTime);

            myTimeStamp = Convert.ToInt64(MyUnixTimestamp / 30);
            myData      = BitConverter.GetBytes(myTimeStamp).Reverse().ToArray();

#if WINDOWS_UWP
            var myBuffer    = CryptographicBuffer.CreateFromByteArray(myData);
            var myKeyBuffer = CryptographicBuffer.CreateFromByteArray(mySecret);

            var myKey          = myCryptprovider.CreateKey(myKeyBuffer);
            var mySignedBuffer = CryptographicEngine.Sign(myKey, myBuffer);

            CryptographicBuffer.CopyToByteArray(mySignedBuffer, out myHmac);
#else
            myHmac = new HMACSHA1(mySecret).ComputeHash(myData);
#endif
            myOffset          = myHmac.Last() & 0x0F;
            myOneTimePassword = (
                ((myHmac[myOffset + 0] & 0x7f) << 24) |
                ((myHmac[myOffset + 1] & 0xff) << 16) |
                ((myHmac[myOffset + 2] & 0xff) << 8) |
                (myHmac[myOffset + 3] & 0xff)
                ) % 1000000;

            return(myOneTimePassword);
        }
        public static string CalculateOneTimePassword(byte[] secret, int slotOffset = 0)
        {
            // https://tools.ietf.org/html/rfc4226
            int steps = 30; // 30 seconds for Google Authentication

            byte[] secretHash        = new MD5CryptoServiceProvider().ComputeHash(secret).Take(10).ToArray();
            Int64  UnixTimestamp     = GetUnixTimestamp();
            Int64  GoodTillTimestamp = Convert.ToInt64(UnixTimestamp / steps) + slotOffset;
            int    SecondsRemain     = steps - Convert.ToInt32(UnixTimestamp % steps);
            var    data = BitConverter.GetBytes(GoodTillTimestamp).Reverse().ToArray();

            byte[] Hmac            = new HMACSHA1(secretHash).ComputeHash(data);
            int    Offset          = Hmac.Last() & 0x0F;
            int    OneTimePassword = (
                ((Hmac[Offset + 0] & 0x7f) << 24) |
                ((Hmac[Offset + 1] & 0xff) << 16) |
                ((Hmac[Offset + 2] & 0xff) << 8) |
                (Hmac[Offset + 3] & 0xff)
                ) % 1000000;

            return(string.Format("{0:000000}", OneTimePassword));
        }
Пример #7
0
        public static string CalculateOneTimePassword(byte[] secret, int slotOffset = 0, int digits = 6)
        {
            // https://tools.ietf.org/html/rfc4226
            int steps = 30; // 30 seconds for Google Authentication

            byte[] secretHash        = HashSecret(secret);
            Int64  UnixTimestamp     = GetUnixTimestamp();
            Int64  GoodTillTimestamp = Convert.ToInt64(UnixTimestamp / steps) + slotOffset;
            int    SecondsRemain     = steps - Convert.ToInt32(UnixTimestamp % steps);
            int    mod       = (int)Math.Pow(10, digits);
            string formatter = string.Format("{{0:{0}}}", mod.ToString().Substring(1));
            var    data      = BitConverter.GetBytes(GoodTillTimestamp).Reverse().ToArray();

            byte[] Hmac            = new HMACSHA1(secretHash).ComputeHash(data);
            int    Offset          = Hmac.Last() & 0x0F;
            int    OneTimePassword = (
                ((Hmac[Offset + 0] & 0x7f) << 24) |
                ((Hmac[Offset + 1] & 0xff) << 16) |
                ((Hmac[Offset + 2] & 0xff) << 8) |
                (Hmac[Offset + 3] & 0xff)
                ) % mod;

            return(string.Format(formatter, OneTimePassword));
        }
Пример #8
0
        //-------------------------------------------------------------------------------------------------
        //--- Check if a provided OTP is valid for the provided GUID (allow 3 past + 3 future ones)
        //-------------------------------------------------------------------------------------------------
        public static async Task <bool> IsValidOTPFromGuid(Guid TheGuid, int TheOTPToCheck, bool UseNetworkTime = false)
        {
            bool success        = false;
            int  myNumberOfOTPs = 7;

            Int64 myTimeStamp;

            byte[] mySecret;
            byte[] myHmac;
            byte[] myData;
            int    myOffset;
            int    myOneTimePassword;
            Int64  MyUnixTimestamp;

            int[] myAllowedOTPArray = new int[myNumberOfOTPs];

            mySecret = StringToBytes(TheGuid.ToString("N"));

#if WINDOWS_UWP
            var myCryptprovider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1);
#else
            HMACSHA1 myCryptprovider = new HMACSHA1(mySecret);
#endif
            MyUnixTimestamp = await GetUnixTimestamp(UseNetworkTime);

            myTimeStamp = Convert.ToInt64(MyUnixTimestamp / 30);
            for (int i = 0; i < myNumberOfOTPs; i++)
            {
                //current timestamp = myTimeStamp(-0)
                //So we allow the previous 3 values and future 3 values as well

                myData = BitConverter.GetBytes(myTimeStamp + i - 3).Reverse().ToArray();

#if WINDOWS_UWP
                var myBuffer    = CryptographicBuffer.CreateFromByteArray(myData);
                var myKeyBuffer = CryptographicBuffer.CreateFromByteArray(mySecret);

                var myKey          = myCryptprovider.CreateKey(myKeyBuffer);
                var mySignedBuffer = CryptographicEngine.Sign(myKey, myBuffer);

                CryptographicBuffer.CopyToByteArray(mySignedBuffer, out myHmac);
#else
                myHmac = new HMACSHA1(mySecret).ComputeHash(myData);
#endif

                myOffset          = myHmac.Last() & 0x0F;
                myOneTimePassword = (
                    ((myHmac[myOffset + 0] & 0x7f) << 24) |
                    ((myHmac[myOffset + 1] & 0xff) << 16) |
                    ((myHmac[myOffset + 2] & 0xff) << 8) |
                    (myHmac[myOffset + 3] & 0xff)
                    ) % 1000000;
                myAllowedOTPArray[i] = myOneTimePassword;
            }

            //do the check
            int index = 0;

            while ((index < myNumberOfOTPs) & (!success))
            {
                success = myAllowedOTPArray[index] == TheOTPToCheck;
                index++;
            }
            return(success);
        }