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