예제 #1
0
        /// <summary>
        /// Construct a filter array.
        /// </summary>
        /// <param name="numberOfBitsInArray">The size of the array in bits.</param>
        /// <param name="maximumBitIndexesPerElement">The maximum (and default) number of indexes (bits) in the array to associate with elements.</param>
        /// <param name="initilizeBitsOfArrayAtRandom">If set to true, the bits of the filter array will be set to 0 or 1 at random (indpendently, each with probability 0.5).</param>
        /// <param name="saltForHashFunctions">A salt used to generate the hash functions.
        /// Any two filter arrays generated with the same salt will use the same hash functions.
        /// The salt should be kept secret from attackerse who might try to manipulate the selection of elements,
        /// such as to intentionally cause bit collisions with the array.</param>
        public FilterArray(int numberOfBitsInArray, int maximumBitIndexesPerElement, bool initilizeBitsOfArrayAtRandom,
                           string saltForHashFunctions = "")
        {
            // Align on byte boundary to guarantee no less than numberOfBitsInArray
            int capacityInBytes = (numberOfBitsInArray + 7) / 8;

            // Create hash functions to map elements to indexes in the bit array.
            HashFunctionsMappingElementsToBitsInTheArray = new UniversalHashFunction[maximumBitIndexesPerElement];
            for (int i = 0; i < HashFunctionsMappingElementsToBitsInTheArray.Length; i++)
            {
                HashFunctionsMappingElementsToBitsInTheArray[i] =
                    new UniversalHashFunction(i + ":" + saltForHashFunctions, 64);
            }

            if (initilizeBitsOfArrayAtRandom)
            {
                // Initialize the bit array setting ~half the bits randomly to zero by using the
                // cryptographic random number generator.
                byte[] initialBitValues = new byte[capacityInBytes];
                StrongRandomNumberGenerator.GetBytes(initialBitValues);
                BitArray = new BitArray(initialBitValues);
            }
            else
            {
                // Start with all bits of the array set to zero.
                BitArray = new BitArray(capacityInBytes * 8);
            }
        }
예제 #2
0
        public async Task CookieUsedInPriorLoginAsync()
        {
            Init();
            string        username          = "******";
            string        password          = "******";
            DbUserAccount account           = userAccountController.Create(username, password);
            string        randomCookiesHash = Convert.ToBase64String(StrongRandomNumberGenerator.GetBytes(16));
            bool          cookieAlreadyPresentOnFirstTest = await
                                                            userAccountController.HasClientWithThisHashedCookieSuccessfullyLoggedInBeforeAsync(account, randomCookiesHash);

            Assert.False(cookieAlreadyPresentOnFirstTest);
            await userAccountController.RecordHashOfDeviceCookieUsedDuringSuccessfulLoginAsync(account, randomCookiesHash);

            bool cookieAlreadyPresentOnSecondTest = await
                                                    userAccountController.HasClientWithThisHashedCookieSuccessfullyLoggedInBeforeAsync(account, randomCookiesHash);

            Assert.True(cookieAlreadyPresentOnSecondTest);
        }
예제 #3
0
        public async Task AddIncorrectPhase2HashAsync()
        {
            Init();
            string        username = "******";
            string        password = "******";
            DbUserAccount account  = userAccountController.Create(username, password);
            string        incorrectPasswordHash = Convert.ToBase64String(StrongRandomNumberGenerator.GetBytes(16));
            bool          incorrectPasswordAlreadyPresentOnFirstTest = await
                                                                       userAccountController.AddIncorrectPhaseTwoHashAsync(account, incorrectPasswordHash);

            Assert.False(incorrectPasswordAlreadyPresentOnFirstTest);
            // Since the hash is added via a background task to minimize response latency, we'll want to
            // wait to be sure it's added
            Thread.Sleep(1000);
            bool incorrectPasswordPresentOnSecondTest = await
                                                        userAccountController.AddIncorrectPhaseTwoHashAsync(account, incorrectPasswordHash);

            Assert.True(incorrectPasswordPresentOnSecondTest);
        }
예제 #4
0
        public FilterArray(int numberOfBitsInArray, int maximumBitIndexesPerElement, bool initilizeBitsOfArrayAtRandom,
                           string saltForHashFunctions = "")
        {
            int capacityInBytes = (numberOfBitsInArray + 7) / 8;

            HashFunctionsMappingElementsToBitsInTheArray = new UniversalHashFunction[maximumBitIndexesPerElement];
            for (int i = 0; i < HashFunctionsMappingElementsToBitsInTheArray.Length; i++)
            {
                HashFunctionsMappingElementsToBitsInTheArray[i] =
                    new UniversalHashFunction(i + ":" + saltForHashFunctions, 64);
            }

            if (initilizeBitsOfArrayAtRandom)
            {
                byte[] initialBitValues = new byte[capacityInBytes];
                StrongRandomNumberGenerator.GetBytes(initialBitValues);
                BitArray = new BitArray(initialBitValues);
            }
            else
            {
                BitArray = new BitArray(capacityInBytes * 8);
            }
        }