Exemplo n.º 1
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);
        }