/// <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); } }
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); }
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); }
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); } }