public void KeysAreRandomBase32(string encodedKey) { var base32AlphabetBytes = Base32Alphabet.ToBytesFromAscii(); var numberOfKeys = Faker.Random.Int(10, 200); var keysWithPossibleDuplicates = new List <string>(); var keysWithNoDuplicates = new HashSet <string>(); $"When I create many ({numberOfKeys}) keys" .x(() => { for (var i = 0; i < numberOfKeys; i++) { encodedKey = TestInstance.CreateKey(); keysWithPossibleDuplicates.Add(encodedKey); keysWithNoDuplicates.Add(encodedKey); } }); "Then encoded keys are random and unique" .x(() => keysWithPossibleDuplicates.Count.ShouldBe(keysWithNoDuplicates.Count)); "And the encoded keys are Base32" .x(() => keysWithNoDuplicates.First().ToBytesFromAscii().ShouldAllBe(x => base32AlphabetBytes.Contains(x))); /* * There is no easy way to test for sufficient randomness as specified in * RFC 4086 https://tools.ietf.org/html/rfc4086. * * Trust the output from System.Security.Cryptography.RandomNumberGenerator */ }
public void KeyIsRecommendedStrengthWhenEncoded(string encodedKey) { "When I create a secret key" .x(() => encodedKey = TestInstance.CreateKey()); "Then the encoded key meets RFC 4226 shared secret recommended length requirement of 160 bits (20 bytes)" .x(() => encodedKey.ShouldSatisfyAllConditions( () => encodedKey.Length.ShouldBe(32), () => TestInstance.DecodeKey(encodedKey).Length.ShouldBe(20) )); }
public void KeyIsRecommendedLengthWhenEncoded(string encodedKey, byte[] hmacHash) { "When I create a secret key" .x(() => encodedKey = TestInstance.CreateKey()); "And an HMAC hash" .x(() => hmacHash = Container.Resolve <TotpTokenBuilder>().GenerateSha1Hash( Faker.Random.Bytes(_hmacKeyByteCount), BitConverter.GetBytes(Faker.Random.Long(1500000000, 1600000000)))); "Then the secret key is the length of the HMAC output as specified in RFC 6238" .x(() => TestInstance.DecodeKey(encodedKey).Length.ShouldBe(hmacHash.Length)); }