/// <summary> /// Generates the HMAC Hash object. /// </summary> /// <param name="key">The string to hash.</param> /// <param name="salt">The salt to use for hashing.</param> /// <param name="prf">The pseudorandom function to use for the hash.</param> /// <param name="iterations">The number of iterations to process over the hash.</param> /// <returns>The hash object.</returns> public static HMACHash HMACHash( string?key, byte[] salt, KeyDerivationPrf prf = HMACHashDelegateConfig.DefaultPseudoRandomFunction, int iterations = HMACHashDelegateConfig.DefaultIterations) { HMACHash retHash = new HMACHash() { PseudoRandomFunction = HashFunction.HMACSHA512, Iterations = iterations, }; if (!string.IsNullOrEmpty(key)) { // The key is not null, so we can generate a hash // Calculate the length in bytes of the hash given the function size int hashLength = prf == KeyDerivationPrf.HMACSHA1 ? 20 : prf == KeyDerivationPrf.HMACSHA256 ? 32 : 64; retHash.Salt = Convert.ToBase64String(salt); retHash.Hash = Convert.ToBase64String(KeyDerivation.Pbkdf2( password: key, salt: salt, prf: prf, iterationCount: iterations, numBytesRequested: hashLength)); } return(retHash); }
static void TestDecryptor() { //------------------------ PRIMARY PAN HASH --------------------------------------------- //string primaryPAN = "34313131313131313131313131313131"; //byte[] data = Encoding.ASCII.GetBytes(primaryPAN); //string dump = ByteArrayToString(data); //string encryptedPrimaryPAN = HMACHash.Encrypt(Encoding.ASCII.GetString(data), HMACValidator.MACSecondaryHASH); //string primaryPANKeySalt = ByteArrayToString(UTF8Encoding.UTF8.GetBytes(encryptedPrimaryPAN)); //0x76, 0x58, 0x38, 0x6c, 0x36, 0x53, 0x4f, 0x6d, 0x53, 0x76, 0x6d, 0x70, 0x57, 0x52, 0x69, 0x36, 0x41, 0x44, 0x6e, 0x53, 0x73, 0x71, 0x6c, 0x5a, 0x47, 0x4c, 0x6f, 0x41, 0x4f, 0x64, 0x4b, 0x79, 0x71, 0x56, 0x6b, 0x59, 0x75, 0x67, 0x41, 0x35, 0x30, 0x72, 0x4b, 0x41, 0x4e, 0x77, 0x4e, 0x41, 0x35, 0x4d, 0x2b, 0x6e, 0x78, 0x41, 0x3d, 0x3d // DECRYPT PRIMARY PAN HASH: "34313131313131313131313131313131" string primaryPANHASH = HMACHash.Decrypt(Encoding.ASCII.GetString(HMACValidator.MACPrimaryPANSalt), HMACValidator.MACSecondaryHASH); Console.WriteLine($"DECRYPTED PRIMARY PAN: {primaryPANHASH}"); //------------------------ PRIMARY HMAC HASH --------------------------------------------- //string primaryHash = "98A8AAED5A2BA9E228B138274FDF546D6688D2AB8D9A36E0A50A5BF3B142AFB0"; //byte[] data = Encoding.ASCII.GetBytes(primaryHash); //string dump = ByteArrayToString(data); //byte[] MACPrimaryHASH = new byte [] { 0x39, 0x38, 0x41, 0x38, 0x41, 0x41, 0x45, 0x44, 0x35, 0x41, 0x32, 0x42, 0x41, 0x39, 0x45, 0x32, 0x32, 0x38, 0x42, 0x31, 0x33, 0x38, 0x32, 0x37, 0x34, 0x46, 0x44, 0x46, 0x35, 0x34, 0x36, 0x44, 0x36, 0x36, 0x38, 0x38, 0x44, 0x32, 0x41, 0x42, 0x38, 0x44, 0x39, 0x41, 0x33, 0x36, 0x45, 0x30, 0x41, 0x35, 0x30, 0x41, 0x35, 0x42, 0x46, 0x33, 0x42, 0x31, 0x34, 0x32, 0x41, 0x46, 0x42, 0x30 }; //string encryptedPrimaryHash = HMACHash.Encrypt(Encoding.ASCII.GetString(data), HMACValidator.MACSecondaryHASH); //string primaryKeySalt = ByteArrayToString(UTF8Encoding.UTF8.GetBytes(encryptedPrimaryHash)); //0x5a, 0x2b, 0x50, 0x66, 0x4d, 0x4c, 0x55, 0x76, 0x36, 0x64, 0x76, 0x46, 0x4f, 0x77, 0x72, 0x31, 0x4d, 0x75, 0x36, 0x50, 0x63, 0x76, 0x58, 0x30, 0x68, 0x45, 0x67, 0x6c, 0x57, 0x71, 0x38, 0x6e, 0x6e, 0x57, 0x74, 0x5a, 0x58, 0x33, 0x2b, 0x6c, 0x45, 0x79, 0x59, 0x38, 0x77, 0x58, 0x37, 0x67, 0x7a, 0x6c, 0x49, 0x56, 0x51, 0x69, 0x53, 0x76, 0x58, 0x65, 0x76, 0x57, 0x66, 0x56, 0x4b, 0x78, 0x6c, 0x6a, 0x45, 0x49, 0x4e, 0x49, 0x52, 0x42, 0x30, 0x2f, 0x43, 0x79, 0x69, 0x51, 0x50, 0x62, 0x4d, 0x55, 0x62, 0x30, 0x36, 0x59, 0x41, 0x33, 0x41, 0x30, 0x44, 0x6b, 0x7a, 0x36, 0x66, 0x45 //Console.WriteLine($"ENCRYPTED PRIMARY HASH: {encrypted}"); //string decrypted = HMACHash.Decrypt(encrypted); //Console.WriteLine($"DECRYPTED PRIMARY HASH: {decrypted}"); // DECRYPT PRIMARY HASH: "98A8AAED5A2BA9E228B138274FDF546D6688D2AB8D9A36E0A50A5BF3B142AFB0" string primaryHASH = HMACHash.Decrypt(Encoding.ASCII.GetString(HMACValidator.MACPrimaryHASHSalt), HMACValidator.MACSecondaryHASH); Console.WriteLine($"DECRYPTED PRIMARY HASH: {primaryHASH}"); //------------------------ SECONDARY HMAC HASH --------------------------------------------- //string secondaryHash = "D1F8827DD9276F9F80F8890D3E607AC03CA022BA91B8024356DCDF54AD434F83"; //byte [] secondaryHashData = Encoding.ASCII.GetBytes(secondaryHash); //string dump = ByteArrayToString(data); //0x44, 0x31, 0x46, 0x38, 0x38, 0x32, 0x37, 0x44, 0x44, 0x39, 0x32, 0x37, 0x36, 0x46, 0x39, 0x46, 0x38, 0x30, 0x46, 0x38, 0x38, 0x39, 0x30, 0x44, 0x33, 0x45, 0x36, 0x30, 0x37, 0x41, 0x43, 0x30, 0x33, 0x43, 0x41, 0x30, 0x32, 0x32, 0x42, 0x41, 0x39, 0x31, 0x42, 0x38, 0x30, 0x32, 0x34, 0x33, 0x35, 0x36, 0x44, 0x43, 0x44, 0x46, 0x35, 0x34, 0x41, 0x44, 0x34, 0x33, 0x34, 0x46, 0x38, 0x33 //string decrypted = HMACHash.Decrypt(Encoding.ASCII.GetString(HMACValidator.MACSecondaryHASH)); //Console.WriteLine($"DECRYPTED PRIMARY HASH: {decrypted}"); //string encryptedSecondaryHash = HMACHash.Encrypt(Encoding.ASCII.GetString(secondaryHashData), HMACValidator.MACPrimaryHASH); //string secondaryKeySalt = ByteArrayToString(UTF8Encoding.UTF8.GetBytes(encryptedSecondaryHash)); //0x69, 0x76, 0x70, 0x7a, 0x71, 0x51, 0x59, 0x4f, 0x38, 0x59, 0x67, 0x6f, 0x51, 0x4c, 0x79, 0x35, 0x36, 0x38, 0x67, 0x73, 0x72, 0x51, 0x53, 0x34, 0x39, 0x62, 0x6f, 0x48, 0x65, 0x52, 0x70, 0x75, 0x37, 0x44, 0x72, 0x37, 0x79, 0x58, 0x6a, 0x4c, 0x32, 0x6d, 0x71, 0x46, 0x45, 0x6e, 0x34, 0x32, 0x56, 0x37, 0x44, 0x41, 0x2f, 0x4c, 0x4e, 0x63, 0x42, 0x70, 0x6d, 0x4e, 0x4d, 0x58, 0x48, 0x6d, 0x6b, 0x43, 0x32, 0x6b, 0x6c, 0x6c, 0x6a, 0x33, 0x32, 0x7a, 0x4b, 0x72, 0x54, 0x69, 0x32, 0x4c, 0x4c, 0x72, 0x54, 0x38, 0x4f, 0x57, 0x2f, 0x4c, 0x6b, 0x41, 0x4a, 0x4e, 0x4f, 0x47, 0x56, 0x73 // DECRYPT SECONDARY HASH: "D1F8827DD9276F9F80F8890D3E607AC03CA022BA91B8024356DCDF54AD434F83" string secondaryHASH = HMACHash.Decrypt(Encoding.ASCII.GetString(HMACValidator.MACSecondaryHASHSalt), HMACValidator.MACPrimaryHASH); Console.WriteLine($"DECRYPTED SECONDARY HASH: {secondaryHASH}"); Console.ReadKey(); }
/// <summary> /// Validates that the supplied key will hash to the compareHash. /// </summary> /// <param name="key">The key to hash and compare.</param> /// <param name="compareHash">The hash object to compare.</param> /// <returns>true if the key generates the same hash.</returns> public static bool Compare(string?key, HMACHash?compareHash) { bool result = false; if (key != null && compareHash != null && compareHash.Hash != null && compareHash.Salt != null) { HMACHash keyHash = HMACHash( key, Convert.FromBase64String(compareHash.Salt), (KeyDerivationPrf)compareHash.PseudoRandomFunction, compareHash.Iterations); result = compareHash.Hash == keyHash.Hash; } else { // If the key is null and the hash is null then they are the same result = compareHash != null && compareHash.Hash == null && key == null; } return(result); }
public void ValidateGetProtectiveWordParseException() { string PHN = "9735361219"; ODRHistoryQuery query = new ODRHistoryQuery() { StartDate = System.DateTime.Parse("1990/01/01"), EndDate = System.DateTime.Now, PHN = PHN, }; var handlerMock = new Mock <HttpMessageHandler>(); ODRConfig odrConfig = new ODRConfig(); string ODRConfigSectionKey = "ODR"; this.configuration.Bind(ODRConfigSectionKey, odrConfig); Uri baseURI = new Uri(odrConfig.BaseEndpoint); Uri protectiveWordEndpoint = new Uri(baseURI, odrConfig.ProtectiveWordEndpoint); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.Is <HttpRequestMessage>(c => c.RequestUri == protectiveWordEndpoint), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent("Bad Data"), }) .Verifiable(); using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); Mock <IGenericCacheDelegate> mockCacheDelegate = new Mock <IGenericCacheDelegate>(); Mock <IHashDelegate> mockHashDelegate = new Mock <IHashDelegate>(); IHash hash = new HMACHash() { Hash = "", }; mockHashDelegate.Setup(s => s.Hash(It.IsAny <string>())).Returns(hash); mockHashDelegate.Setup(s => s.Compare(It.IsAny <string>(), It.IsAny <IHash>())).Returns(true); Mock <IHttpClientService> mockHttpClientService = new Mock <IHttpClientService>(); mockHttpClientService.Setup(s => s.CreateDefaultHttpClient()).Returns(() => new HttpClient(handlerMock.Object)); IMedStatementDelegate medStatementDelegate = new RestMedStatementDelegate(loggerFactory.CreateLogger <RestMedStatementDelegate>(), mockHttpClientService.Object, this.configuration, mockCacheDelegate.Object, mockHashDelegate.Object); RequestResult <MedicationHistoryResponse> response = Task.Run(async() => await medStatementDelegate.GetMedicationStatementsAsync( query, string.Empty, string.Empty, string.Empty).ConfigureAwait(true)).Result; Assert.True(response.ResultStatus == Common.Constants.ResultType.Protected); }
public void ValidateGetMedicationStatement() { string PHN = "9735361219"; string HDID = "EXTRIOYFPNX35TWEBUAJ3DNFDFXSYTBC6J4M76GYE3HC5ER2NKWQ"; string IP = "10.0.0.1"; ODRHistoryQuery query = new ODRHistoryQuery() { StartDate = System.DateTime.Parse("1990/01/01"), EndDate = System.DateTime.Now, PHN = PHN, }; ProtectiveWord protectiveWord = new ProtectiveWord() { Id = Guid.Parse("ed428f08-1c07-4439-b2a3-acbb16b8fb65"), RequestorHDID = HDID, RequestorIP = IP, QueryResponse = new ProtectiveWordQueryResponse() { PHN = PHN, Operator = Constants.ProtectiveWordOperator.Get, Value = string.Empty, } }; string protectiveWordjson = JsonSerializer.Serialize(protectiveWord); MedicationHistory medicationHistory = new MedicationHistory() { Id = Guid.Parse("ee37267e-cb2c-48e1-a3c9-16c36ce7466b"), RequestorHDID = HDID, RequestorIP = IP, Query = query, Response = new MedicationHistoryResponse() { Id = Guid.Parse("ee37267e-cb2c-48e1-a3c9-16c36ce7466b"), Pages = 1, TotalRecords = 1, Results = new List <Models.ODR.MedicationResult>() { new Models.ODR.MedicationResult() { DIN = "00000000", Directions = "Directions", DispenseDate = DateTime.Now, DispensingPharmacy = new Pharmacy() { Address = new Address() { City = "City", Country = "Country", Line1 = "Line 1", Line2 = "Line 2", PostalCode = "A1A 1A1", Province = "PR", }, FaxNumber = "1111111111", Name = "Name", PharmacyId = "ID", PhoneNumber = "2222222222", }, GenericName = "Generic Name", Id = 0, Practioner = new Name() { GivenName = "Given", MiddleInitial = "I", Surname = "Surname", }, PrescriptionNumber = "Number", PrescriptionStatus = "F", Quantity = 1, Refills = 1, }, }, } }; string meedicationHistoryjson = JsonSerializer.Serialize(medicationHistory); var handlerMock = new Mock <HttpMessageHandler>(); ODRConfig odrConfig = new ODRConfig(); string ODRConfigSectionKey = "ODR"; this.configuration.Bind(ODRConfigSectionKey, odrConfig); Uri baseURI = new Uri(odrConfig.BaseEndpoint); Uri patientProfileEndpoint = new Uri(baseURI, odrConfig.PatientProfileEndpoint); Uri protectiveWordEndpoint = new Uri(baseURI, odrConfig.ProtectiveWordEndpoint); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.Is <HttpRequestMessage>(c => c.RequestUri == patientProfileEndpoint), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(meedicationHistoryjson), }) .Verifiable(); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.Is <HttpRequestMessage>(c => c.RequestUri == protectiveWordEndpoint), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(protectiveWordjson), }) .Verifiable(); using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); Mock <IGenericCacheDelegate> mockCacheDelegate = new Mock <IGenericCacheDelegate>(); Mock <IHashDelegate> mockHashDelegate = new Mock <IHashDelegate>(); IHash hash = new HMACHash() { Hash = "", }; mockHashDelegate.Setup(s => s.Hash(It.IsAny <string>())).Returns(hash); mockHashDelegate.Setup(s => s.Compare(It.IsAny <string>(), It.IsAny <IHash>())).Returns(true); Mock <IHttpClientService> mockHttpClientService = new Mock <IHttpClientService>(); mockHttpClientService.Setup(s => s.CreateDefaultHttpClient()).Returns(() => new HttpClient(handlerMock.Object)); IMedStatementDelegate medStatementDelegate = new RestMedStatementDelegate(loggerFactory.CreateLogger <RestMedStatementDelegate>(), mockHttpClientService.Object, this.configuration, mockCacheDelegate.Object, mockHashDelegate.Object); RequestResult <MedicationHistoryResponse> response = Task.Run(async() => await medStatementDelegate.GetMedicationStatementsAsync( query, string.Empty, string.Empty, string.Empty).ConfigureAwait(true)).Result; Assert.True(response.ResultStatus == Common.Constants.ResultType.Success && medicationHistory.Response.IsDeepEqual(response.ResourcePayload)); }
public void ValidateGetMedicationStatementHttpException() { string PHN = "9735361219"; string HDID = "EXTRIOYFPNX35TWEBUAJ3DNFDFXSYTBC6J4M76GYE3HC5ER2NKWQ"; string IP = "10.0.0.1"; ODRHistoryQuery query = new ODRHistoryQuery() { StartDate = System.DateTime.Parse("1990/01/01"), EndDate = System.DateTime.Now, PHN = PHN, }; ProtectiveWord protectiveWord = new ProtectiveWord() { Id = Guid.Parse("ed428f08-1c07-4439-b2a3-acbb16b8fb65"), RequestorHDID = HDID, RequestorIP = IP, QueryResponse = new ProtectiveWordQueryResponse() { PHN = PHN, Operator = Constants.ProtectiveWordOperator.Get, Value = string.Empty, } }; string protectiveWordjson = JsonSerializer.Serialize(protectiveWord); var handlerMock = new Mock <HttpMessageHandler>(); ODRConfig odrConfig = new ODRConfig(); string ODRConfigSectionKey = "ODR"; this.configuration.Bind(ODRConfigSectionKey, odrConfig); Uri baseURI = new Uri(odrConfig.BaseEndpoint); Uri patientProfileEndpoint = new Uri(baseURI, odrConfig.PatientProfileEndpoint); Uri protectiveWordEndpoint = new Uri(baseURI, odrConfig.ProtectiveWordEndpoint); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.Is <HttpRequestMessage>(c => c.RequestUri == patientProfileEndpoint), ItExpr.IsAny <CancellationToken>() ) .Throws <HttpRequestException>() .Verifiable(); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.Is <HttpRequestMessage>(c => c.RequestUri == protectiveWordEndpoint), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(protectiveWordjson), }) .Verifiable(); using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); Mock <IGenericCacheDelegate> mockCacheDelegate = new Mock <IGenericCacheDelegate>(); Mock <IHashDelegate> mockHashDelegate = new Mock <IHashDelegate>(); IHash hash = new HMACHash() { Hash = "", }; mockHashDelegate.Setup(s => s.Hash(It.IsAny <string>())).Returns(hash); mockHashDelegate.Setup(s => s.Compare(It.IsAny <string>(), It.IsAny <IHash>())).Returns(true); Mock <IHttpClientService> mockHttpClientService = new Mock <IHttpClientService>(); mockHttpClientService.Setup(s => s.CreateDefaultHttpClient()).Returns(() => new HttpClient(handlerMock.Object)); IMedStatementDelegate medStatementDelegate = new RestMedStatementDelegate(loggerFactory.CreateLogger <RestMedStatementDelegate>(), mockHttpClientService.Object, this.configuration, mockCacheDelegate.Object, mockHashDelegate.Object); RequestResult <MedicationHistoryResponse> response = Task.Run(async() => await medStatementDelegate.GetMedicationStatementsAsync( query, string.Empty, string.Empty, string.Empty).ConfigureAwait(true)).Result; Assert.True(response.ResultStatus == Common.Constants.ResultType.Error); }