From 30ec65c43b35ebe46ef7c7327b327b150e7a0f18 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Wed, 20 Mar 2024 13:34:51 +0800 Subject: [PATCH 1/5] check system endianness --- .../Targeting/TargetingEvaluator.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs index cc809e27..3b591241 100644 --- a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs +++ b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs @@ -349,9 +349,21 @@ private static bool IsTargeted(string contextId, double from, double to) } // - // Use first 4 bytes for percentage calculation + // The first 4 bytes of the hash will be used for percentage calculation + byte[] relevantBytes = new byte[4]; + + Array.Copy(hash, 0, relevantBytes, 0, 4); + + // + // If the system is not little-endian, reverse the bytes. + if (!BitConverter.IsLittleEndian) + { + Array.Reverse(relevantBytes); + } + + // // Cryptographic hashing algorithms ensure adequate entropy across hash - uint contextMarker = BitConverter.ToUInt32(hash, 0); + uint contextMarker = BitConverter.ToUInt32(relevantBytes, 0); double contextPercentage = (contextMarker / (double)uint.MaxValue) * 100; From 4eeed5807f271e1becb1b6a01912f820c7b8f742 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Wed, 20 Mar 2024 13:41:39 +0800 Subject: [PATCH 2/5] remove period --- src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs index 3b591241..38d0108e 100644 --- a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs +++ b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs @@ -355,7 +355,7 @@ private static bool IsTargeted(string contextId, double from, double to) Array.Copy(hash, 0, relevantBytes, 0, 4); // - // If the system is not little-endian, reverse the bytes. + // If the system is not little-endian, reverse the bytes if (!BitConverter.IsLittleEndian) { Array.Reverse(relevantBytes); From a8bbe489c8bff57c32808137d24ddc189c838ba1 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Thu, 21 Mar 2024 10:36:51 +0800 Subject: [PATCH 3/5] update reverse method --- .../Targeting/TargetingEvaluator.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs index 38d0108e..d85ad15a 100644 --- a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs +++ b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs @@ -348,22 +348,18 @@ private static bool IsTargeted(string contextId, double from, double to) hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(contextId)); } - // - // The first 4 bytes of the hash will be used for percentage calculation - byte[] relevantBytes = new byte[4]; - - Array.Copy(hash, 0, relevantBytes, 0, 4); // - // If the system is not little-endian, reverse the bytes + // The first 4 bytes of the hash will be used for percentage calculation + // Endianness check ensures the consistency accross different architectures if (!BitConverter.IsLittleEndian) { - Array.Reverse(relevantBytes); + Array.Reverse(hash, 0, 4); } // // Cryptographic hashing algorithms ensure adequate entropy across hash - uint contextMarker = BitConverter.ToUInt32(relevantBytes, 0); + uint contextMarker = BitConverter.ToUInt32(hash, 0); double contextPercentage = (contextMarker / (double)uint.MaxValue) * 100; From ec9ae1589ad9adcec4a879813ff34c3cf1f65761 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Thu, 28 Mar 2024 11:12:41 +0800 Subject: [PATCH 4/5] update comment --- src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs index d85ad15a..e216a161 100644 --- a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs +++ b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs @@ -351,7 +351,7 @@ private static bool IsTargeted(string contextId, double from, double to) // // The first 4 bytes of the hash will be used for percentage calculation - // Endianness check ensures the consistency accross different architectures + // Endianness check ensures the consistency of targeting evaluation result across different architectures if (!BitConverter.IsLittleEndian) { Array.Reverse(hash, 0, 4); From 17e13d838f155781d3f00820721e98dc86a54461 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Wed, 3 Apr 2024 10:11:14 +0800 Subject: [PATCH 5/5] adjust comment --- .../Targeting/TargetingEvaluator.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs index e216a161..5c8ed8b1 100644 --- a/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs +++ b/src/Microsoft.FeatureManagement/Targeting/TargetingEvaluator.cs @@ -343,6 +343,8 @@ private static bool IsTargeted(string contextId, double from, double to) { byte[] hash; + // + // Cryptographic hashing algorithms ensure adequate entropy across hash using (HashAlgorithm hashAlgorithm = SHA256.Create()) { hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(contextId)); @@ -350,7 +352,6 @@ private static bool IsTargeted(string contextId, double from, double to) // - // The first 4 bytes of the hash will be used for percentage calculation // Endianness check ensures the consistency of targeting evaluation result across different architectures if (!BitConverter.IsLittleEndian) { @@ -358,7 +359,7 @@ private static bool IsTargeted(string contextId, double from, double to) } // - // Cryptographic hashing algorithms ensure adequate entropy across hash + // The first 4 bytes of the hash will be used for percentage calculation uint contextMarker = BitConverter.ToUInt32(hash, 0); double contextPercentage = (contextMarker / (double)uint.MaxValue) * 100;