public void GeneratePasswordReturnsPassword()
        {
            var hashService = Substitute.For<IHashService>();
            var hash = new byte[] {0, 0, 0, 0, 0, 0, 0, 0};
            var expectedHash = new byte[] { 0, 0, 0, 0 };
            hashService.Hash(Arg.Any<byte[]>(), Arg.Any<byte[]>(), Arg.Any<int>(), Arg.Any<int>(), Arg.Any<int>())
                .Returns(ci=>hash);
            var controller = CreateController(hashService: hashService);
            var passwordRequest = new PasswordRequest()
                                      {
                                          HashLength = 64,
                                          Iterations = 1000,
                                          MaximumWordLength = 12,
                                          MinimumWordLength = 6,
                                          PassPhrase = "password",
                                          SaltLength = 16,
                                          SourceType = SourceType.Manual,
                                          WordComplexity = 1000,
                                          WordCount = 0
                                      };
            var password = controller.GeneratePassword(passwordRequest);

            IStructuralEquatable output = password.Model.Hash;
            Assert.True(output.Equals(expectedHash, StructuralComparisons.StructuralEqualityComparer));
        }
        public JsonResult<Password> GeneratePassword(PasswordRequest passwordRequest)
        {
            if (passwordRequest.WordCount > 6)
                return null;

            if (passwordRequest.HashLength > 1024)
                return null;

            if (passwordRequest.SaltLength > passwordRequest.HashLength * 0.5m)
                return null;

            if (passwordRequest.Iterations > 10000)
                return null;

            byte[] passPhraseBytes;
            var salt = _hashService.CreateSalt(passwordRequest.SaltLength);
            string[] passwordElements;

            if (passwordRequest.SourceType == SourceType.Auto)
            {
                var wordTask = _wordService.RandomWords(passwordRequest.MinimumWordLength, passwordRequest.WordCount,
                                                        passwordRequest.MaximumWordLength,
                                                        passwordRequest.WordComplexity);
                wordTask.Wait();
                passwordElements = wordTask.Result.Select(w => w.Word).ToArray();
                passPhraseBytes = Encoding.UTF8.GetBytes(string.Join(string.Empty, passwordElements));
            }
            else
            {
                passPhraseBytes = Encoding.UTF8.GetBytes(string.Join(string.Empty, passwordRequest.PassPhrase));
                passwordElements = new[] {passwordRequest.PassPhrase};
            }

            var hash = _hashService.Hash(passPhraseBytes, salt, passwordRequest.Iterations, passwordRequest.HashLength + 4);//pad length as we will remove the version number

            var password = new Password
                               {
                                   Hash = hash.Skip(4).ToArray(),//crop the version number from the start
                                   HashSalt = salt,
                                   PasswordElements = passwordElements,
                                   SourceType = passwordRequest.SourceType
                               };

            return new JsonResult<Password>(password);
        }