From bb6dc465ccc75def9ec8afa74a9a6b254333fdac Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Thu, 13 Apr 2017 16:34:12 +0200 Subject: [PATCH 1/6] - extracted generation of hashes to cryptoextensions - added regression tests in order to trigger changes in hash generation --- Piwik.Tracker.Tests/CryptoExtensionsTests.cs | 70 +++++++++++++++++++ .../Piwik.Tracker.Tests.csproj | 1 + Piwik.Tracker/CryptoExtensions.cs | 61 ++++++++++++++++ Piwik.Tracker/Piwik.Tracker.csproj | 1 + Piwik.Tracker/PiwikTracker.cs | 29 +++----- 5 files changed, 141 insertions(+), 21 deletions(-) create mode 100644 Piwik.Tracker.Tests/CryptoExtensionsTests.cs create mode 100644 Piwik.Tracker/CryptoExtensions.cs diff --git a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs new file mode 100644 index 0000000..b04217c --- /dev/null +++ b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs @@ -0,0 +1,70 @@ +using System.Text; +using NUnit.Framework; + +namespace Piwik.Tracker.Tests +{ + [TestFixture] + internal class CryptoExtensionsTests + { + [Test] + [TestCase("", "D41D8CD98F00B204E9800998ECF8427E")] + [TestCase(" ", "7215EE9C7D9DC229D2921A40E899EC5F")] + [TestCase("1234dsfa", "0FFDCBA8AFFF5812719B3BF2D0E80558")] + [TestCase("1-2-3-45-6", "5B727BB9E9C69B60E233C9DCFE52D2E8")] + [TestCase("öüüä%&&", "13EB37F4B5505F21E9E875FBF489E22B")] + [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + public void CreateMd5_RegressionTests(string valueToEncrypt, string expectedHash) + { + //Act + var actualHash = valueToEncrypt.CreateMd5(); + //Assert + Assert.That(actualHash, Is.EqualTo(expectedHash)); + } + + [Test] + // Utf8 encoding + [TestCase(true, "", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] + [TestCase(true, " ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] + [TestCase(true, "1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] + [TestCase(true, "1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] + [TestCase(true, "öüüä%&&", "C2-4E-B4-68-5C-D5-7F-32-09-8B-33-06-6B-5B-08-B3-1E-37-89-81")] + [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "BD-E6-CF-18-1D-D5-BC-0E-F1-13-42-D5-C6-A4-E8-1A-93-4D-9C-B8")] + // Default encoding + [TestCase(false, "", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] + [TestCase(false, " ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] + [TestCase(false, "1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] + [TestCase(false, "1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] + [TestCase(false, "öüüä%&&", "90-82-E4-37-59-8F-22-B2-6F-5F-8B-74-FF-E0-2F-B5-4A-FA-45-BB")] + [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "FC-66-DA-AD-A5-65-E4-E9-F3-6A-BF-FE-C6-EC-53-BD-19-71-01-8D")] + public void CreateSha1_RegressionTests(bool utf8, string valueToEncrypt, string expectedHash) + { + //Act + var actualHash = valueToEncrypt.CreateSha1(utf8 ? Encoding.UTF8 : Encoding.Default, hashAsHexadecimal: false); + //Assert + Assert.That(actualHash, Is.EqualTo(expectedHash)); + } + + [Test] + // Utf8 encoding + [TestCase(true, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] + [TestCase(true, " ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] + [TestCase(true, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] + [TestCase(true, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] + [TestCase(true, "öüüä%&&", "c24eb4685cd57f32098b33066b5b08b31e378981")] + [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + // Default encoding + [TestCase(false, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] + [TestCase(false, " ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] + [TestCase(false, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] + [TestCase(false, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] + [TestCase(false, "öüüä%&&", "9082e437598f22b26f5f8b74ffe02fb54afa45bb")] + [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(bool utf8, string valueToEncrypt, string expectedHash) + { + //Act + var actualHash = valueToEncrypt.CreateSha1(utf8 ? Encoding.UTF8 : Encoding.Default, hashAsHexadecimal: true); + //Assert + Assert.That(actualHash, Is.EqualTo(expectedHash)); + } + } +} \ No newline at end of file diff --git a/Piwik.Tracker.Tests/Piwik.Tracker.Tests.csproj b/Piwik.Tracker.Tests/Piwik.Tracker.Tests.csproj index 2a05905..07ccdb3 100644 --- a/Piwik.Tracker.Tests/Piwik.Tracker.Tests.csproj +++ b/Piwik.Tracker.Tests/Piwik.Tracker.Tests.csproj @@ -84,6 +84,7 @@ + diff --git a/Piwik.Tracker/CryptoExtensions.cs b/Piwik.Tracker/CryptoExtensions.cs new file mode 100644 index 0000000..a94fca5 --- /dev/null +++ b/Piwik.Tracker/CryptoExtensions.cs @@ -0,0 +1,61 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace Piwik.Tracker +{ + internal static class CryptoExtensions + { + /// + /// Creates a sha1 hash from given . + /// + /// The value to encrypt. + /// The encoding. + /// if set to true resulting hash will be formated as hexadecimal string. + /// + public static string CreateSha1(this string valueToEncrypt, Encoding encoding, bool hashAsHexadecimal) + { + using (var provider = new SHA1CryptoServiceProvider()) + { + var bytes = encoding.GetBytes(valueToEncrypt); + var encodedBytes = provider.ComputeHash(bytes); + if (hashAsHexadecimal) + { + return GetHexStringFromBytes(encodedBytes); + } + return BitConverter.ToString(encodedBytes); + } + } + + /// + /// Creates the a MD5 hash from given . + /// + /// The value to encrypt. + internal static string CreateMd5(this string valueToEncrypt) + { + using (var provider = new MD5CryptoServiceProvider()) + { + var bytes = Encoding.Default.GetBytes(valueToEncrypt); + var encodedBytes = provider.ComputeHash(bytes); + var hash = BitConverter.ToString(encodedBytes); + return hash.Replace("-", ""); + } + } + + /// + /// Gets the hexadecimal string from bytes. + /// + /// The bytes. + /// + private static string GetHexStringFromBytes(byte[] bytes) + { + var sb = new StringBuilder(); + foreach (byte b in bytes) + { + var hex = b.ToString("x2"); + sb.Append(hex); + } + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Piwik.Tracker/Piwik.Tracker.csproj b/Piwik.Tracker/Piwik.Tracker.csproj index 2c152b9..9ab6c6d 100644 --- a/Piwik.Tracker/Piwik.Tracker.csproj +++ b/Piwik.Tracker/Piwik.Tracker.csproj @@ -46,6 +46,7 @@ + diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index 0f6d0fb..d7beea1 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -431,8 +431,7 @@ public void ClearCustomTrackingParameters() /// public void SetNewVisitorId() { - var encodedGuidBytes = new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(Guid.NewGuid().ToString())); - _randomVisitorId = BitConverter.ToString(encodedGuidBytes).Replace("-", "").Substring(0, LengthVisitorId).ToLower(); + _randomVisitorId = Guid.NewGuid().ToString().CreateMd5().Substring(0, LengthVisitorId).ToLower(); _userId = null; _forcedVisitorId = null; _cookieVisitorId = null; @@ -575,26 +574,14 @@ protected static string DomainFixup(string domain) protected string GetCookieName(string cookieName) { // NOTE: If the cookie name is changed, we must also update the method in piwik.js with the same name. - var hash = GetHexStringFromBytes(new SHA1CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes((string.IsNullOrWhiteSpace(_configCookieDomain) ? GetCurrentHost() : _configCookieDomain) + _configCookiePath))).Substring(0, 4); + var cookieDomain = (string.IsNullOrWhiteSpace(_configCookieDomain) + ? GetCurrentHost() + : _configCookieDomain) + + _configCookiePath; + var hash = cookieDomain.CreateSha1(Encoding.UTF8, hashAsHexadecimal: true).Substring(0, 4); return FirstPartyCookiesPrefix + cookieName + "." + IdSite + "." + hash; } - /// - /// Gets the hexadecimal string from bytes. - /// - /// The bytes. - /// - protected static string GetHexStringFromBytes(byte[] bytes) - { - var sb = new StringBuilder(); - foreach (byte b in bytes) - { - var hex = b.ToString("x2"); - sb.Append(hex); - } - return sb.ToString(); - } - /// /// Tracks a page view /// @@ -1177,8 +1164,8 @@ public void SetUserId(string userId) /// public static string GetUserIdHashed(string id) { - var encodedIdBytes = new SHA1CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(id)); - return BitConverter.ToString(encodedIdBytes).Substring(0, 16); + var hash = id.CreateSha1(Encoding.Default, hashAsHexadecimal: false); + return hash.Substring(0, 16); } /// From a4940207d8e97fde2c7c797073a52a76c61d7ba3 Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Thu, 13 Apr 2017 17:14:15 +0200 Subject: [PATCH 2/6] fixed 2 false positive test expectations --- Piwik.Tracker.Tests/CryptoExtensionsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs index b04217c..a97ef1f 100644 --- a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs +++ b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs @@ -51,14 +51,14 @@ public void CreateSha1_RegressionTests(bool utf8, string valueToEncrypt, string [TestCase(true, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] [TestCase(true, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] [TestCase(true, "öüüä%&&", "c24eb4685cd57f32098b33066b5b08b31e378981")] - [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "bde6cf181dd5bc0ef11342d5c6a4e81a934d9cb8")] // Default encoding [TestCase(false, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] [TestCase(false, " ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] [TestCase(false, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] [TestCase(false, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] [TestCase(false, "öüüä%&&", "9082e437598f22b26f5f8b74ffe02fb54afa45bb")] - [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "fc66daada565e4e9f36abffec6ec53bd1971018d")] public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(bool utf8, string valueToEncrypt, string expectedHash) { //Act From 966afcebf4d75e138702515464e32f5e61284066 Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Thu, 13 Apr 2017 18:56:32 +0200 Subject: [PATCH 3/6] introduced explicit usage of UTF8 encoding for hash generation --- Piwik.Tracker.Tests/CryptoExtensionsTests.cs | 55 +++++++------------- Piwik.Tracker/CryptoExtensions.cs | 7 ++- Piwik.Tracker/PiwikTracker.cs | 4 +- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs index a97ef1f..fd2587f 100644 --- a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs +++ b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs @@ -1,5 +1,4 @@ -using System.Text; -using NUnit.Framework; +using NUnit.Framework; namespace Piwik.Tracker.Tests { @@ -11,8 +10,8 @@ internal class CryptoExtensionsTests [TestCase(" ", "7215EE9C7D9DC229D2921A40E899EC5F")] [TestCase("1234dsfa", "0FFDCBA8AFFF5812719B3BF2D0E80558")] [TestCase("1-2-3-45-6", "5B727BB9E9C69B60E233C9DCFE52D2E8")] - [TestCase("öüüä%&&", "13EB37F4B5505F21E9E875FBF489E22B")] - [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "F77A4A9DFFCB33CB8D7CE078A6DE1BAA")] + [TestCase("öüüä%&&", "C80DE2DAEAC3452AF45FA7F6D957460F")] + [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "A81468398BB34262D16DA35D3B6048D6")] public void CreateMd5_RegressionTests(string valueToEncrypt, string expectedHash) { //Act @@ -22,47 +21,31 @@ public void CreateMd5_RegressionTests(string valueToEncrypt, string expectedHash } [Test] - // Utf8 encoding - [TestCase(true, "", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] - [TestCase(true, " ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] - [TestCase(true, "1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] - [TestCase(true, "1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] - [TestCase(true, "öüüä%&&", "C2-4E-B4-68-5C-D5-7F-32-09-8B-33-06-6B-5B-08-B3-1E-37-89-81")] - [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "BD-E6-CF-18-1D-D5-BC-0E-F1-13-42-D5-C6-A4-E8-1A-93-4D-9C-B8")] - // Default encoding - [TestCase(false, "", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] - [TestCase(false, " ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] - [TestCase(false, "1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] - [TestCase(false, "1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] - [TestCase(false, "öüüä%&&", "90-82-E4-37-59-8F-22-B2-6F-5F-8B-74-FF-E0-2F-B5-4A-FA-45-BB")] - [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "FC-66-DA-AD-A5-65-E4-E9-F3-6A-BF-FE-C6-EC-53-BD-19-71-01-8D")] - public void CreateSha1_RegressionTests(bool utf8, string valueToEncrypt, string expectedHash) + [TestCase("", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] + [TestCase(" ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] + [TestCase("1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] + [TestCase("1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] + [TestCase("öüüä%&&", "C2-4E-B4-68-5C-D5-7F-32-09-8B-33-06-6B-5B-08-B3-1E-37-89-81")] + [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "BD-E6-CF-18-1D-D5-BC-0E-F1-13-42-D5-C6-A4-E8-1A-93-4D-9C-B8")] + public void CreateSha1_RegressionTests(string valueToEncrypt, string expectedHash) { //Act - var actualHash = valueToEncrypt.CreateSha1(utf8 ? Encoding.UTF8 : Encoding.Default, hashAsHexadecimal: false); + var actualHash = valueToEncrypt.CreateSha1(hashAsHexadecimal: false); //Assert Assert.That(actualHash, Is.EqualTo(expectedHash)); } [Test] - // Utf8 encoding - [TestCase(true, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] - [TestCase(true, " ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] - [TestCase(true, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] - [TestCase(true, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] - [TestCase(true, "öüüä%&&", "c24eb4685cd57f32098b33066b5b08b31e378981")] - [TestCase(true, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "bde6cf181dd5bc0ef11342d5c6a4e81a934d9cb8")] - // Default encoding - [TestCase(false, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] - [TestCase(false, " ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] - [TestCase(false, "1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] - [TestCase(false, "1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] - [TestCase(false, "öüüä%&&", "9082e437598f22b26f5f8b74ffe02fb54afa45bb")] - [TestCase(false, "+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "fc66daada565e4e9f36abffec6ec53bd1971018d")] - public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(bool utf8, string valueToEncrypt, string expectedHash) + [TestCase("", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] + [TestCase(" ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] + [TestCase("1234dsfa", "644977634278d36d5f451961fe19622ab13cec87")] + [TestCase("1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] + [TestCase("öüüä%&&", "c24eb4685cd57f32098b33066b5b08b31e378981")] + [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "bde6cf181dd5bc0ef11342d5c6a4e81a934d9cb8")] + public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(string valueToEncrypt, string expectedHash) { //Act - var actualHash = valueToEncrypt.CreateSha1(utf8 ? Encoding.UTF8 : Encoding.Default, hashAsHexadecimal: true); + var actualHash = valueToEncrypt.CreateSha1(hashAsHexadecimal: true); //Assert Assert.That(actualHash, Is.EqualTo(expectedHash)); } diff --git a/Piwik.Tracker/CryptoExtensions.cs b/Piwik.Tracker/CryptoExtensions.cs index a94fca5..36dab0a 100644 --- a/Piwik.Tracker/CryptoExtensions.cs +++ b/Piwik.Tracker/CryptoExtensions.cs @@ -10,14 +10,13 @@ internal static class CryptoExtensions /// Creates a sha1 hash from given . /// /// The value to encrypt. - /// The encoding. /// if set to true resulting hash will be formated as hexadecimal string. /// - public static string CreateSha1(this string valueToEncrypt, Encoding encoding, bool hashAsHexadecimal) + public static string CreateSha1(this string valueToEncrypt, bool hashAsHexadecimal) { using (var provider = new SHA1CryptoServiceProvider()) { - var bytes = encoding.GetBytes(valueToEncrypt); + var bytes = Encoding.UTF8.GetBytes(valueToEncrypt); var encodedBytes = provider.ComputeHash(bytes); if (hashAsHexadecimal) { @@ -35,7 +34,7 @@ internal static string CreateMd5(this string valueToEncrypt) { using (var provider = new MD5CryptoServiceProvider()) { - var bytes = Encoding.Default.GetBytes(valueToEncrypt); + var bytes = Encoding.UTF8.GetBytes(valueToEncrypt); var encodedBytes = provider.ComputeHash(bytes); var hash = BitConverter.ToString(encodedBytes); return hash.Replace("-", ""); diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index d7beea1..76cc9b3 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -578,7 +578,7 @@ protected string GetCookieName(string cookieName) ? GetCurrentHost() : _configCookieDomain) + _configCookiePath; - var hash = cookieDomain.CreateSha1(Encoding.UTF8, hashAsHexadecimal: true).Substring(0, 4); + var hash = cookieDomain.CreateSha1(hashAsHexadecimal: true).Substring(0, 4); return FirstPartyCookiesPrefix + cookieName + "." + IdSite + "." + hash; } @@ -1164,7 +1164,7 @@ public void SetUserId(string userId) /// public static string GetUserIdHashed(string id) { - var hash = id.CreateSha1(Encoding.Default, hashAsHexadecimal: false); + var hash = id.CreateSha1(hashAsHexadecimal: false); return hash.Substring(0, 16); } From 3b6c75a536e459d5ed1236a4745000846e9a49f6 Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Thu, 13 Apr 2017 19:27:31 +0200 Subject: [PATCH 4/6] - Sha1 removes hyphens now by default - removed md5 hash method - implemented usage of Sha1 hash generation method => SetNewVisitorId changed from md5 to sha1; GetUserIdHashed changed from Sha1 with hyphens to sha1 without hyphens --- Piwik.Tracker.Tests/CryptoExtensionsTests.cs | 32 +------------- Piwik.Tracker/CryptoExtensions.cs | 45 +++----------------- Piwik.Tracker/PiwikTracker.cs | 6 +-- 3 files changed, 11 insertions(+), 72 deletions(-) diff --git a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs index fd2587f..63b3173 100644 --- a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs +++ b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs @@ -5,36 +5,6 @@ namespace Piwik.Tracker.Tests [TestFixture] internal class CryptoExtensionsTests { - [Test] - [TestCase("", "D41D8CD98F00B204E9800998ECF8427E")] - [TestCase(" ", "7215EE9C7D9DC229D2921A40E899EC5F")] - [TestCase("1234dsfa", "0FFDCBA8AFFF5812719B3BF2D0E80558")] - [TestCase("1-2-3-45-6", "5B727BB9E9C69B60E233C9DCFE52D2E8")] - [TestCase("öüüä%&&", "C80DE2DAEAC3452AF45FA7F6D957460F")] - [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "A81468398BB34262D16DA35D3B6048D6")] - public void CreateMd5_RegressionTests(string valueToEncrypt, string expectedHash) - { - //Act - var actualHash = valueToEncrypt.CreateMd5(); - //Assert - Assert.That(actualHash, Is.EqualTo(expectedHash)); - } - - [Test] - [TestCase("", "DA-39-A3-EE-5E-6B-4B-0D-32-55-BF-EF-95-60-18-90-AF-D8-07-09")] - [TestCase(" ", "B8-58-CB-28-26-17-FB-09-56-D9-60-21-5C-8E-84-D1-CC-F9-09-C6")] - [TestCase("1234dsfa", "64-49-77-63-42-78-D3-6D-5F-45-19-61-FE-19-62-2A-B1-3C-EC-87")] - [TestCase("1-2-3-45-6", "5C-13-BF-8B-7F-F1-D4-38-69-A7-B4-24-6B-EF-89-7F-94-99-83-3B")] - [TestCase("öüüä%&&", "C2-4E-B4-68-5C-D5-7F-32-09-8B-33-06-6B-5B-08-B3-1E-37-89-81")] - [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "BD-E6-CF-18-1D-D5-BC-0E-F1-13-42-D5-C6-A4-E8-1A-93-4D-9C-B8")] - public void CreateSha1_RegressionTests(string valueToEncrypt, string expectedHash) - { - //Act - var actualHash = valueToEncrypt.CreateSha1(hashAsHexadecimal: false); - //Assert - Assert.That(actualHash, Is.EqualTo(expectedHash)); - } - [Test] [TestCase("", "da39a3ee5e6b4b0d3255bfef95601890afd80709")] [TestCase(" ", "b858cb282617fb0956d960215c8e84d1ccf909c6")] @@ -45,7 +15,7 @@ public void CreateSha1_RegressionTests(string valueToEncrypt, string expectedHas public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(string valueToEncrypt, string expectedHash) { //Act - var actualHash = valueToEncrypt.CreateSha1(hashAsHexadecimal: true); + var actualHash = valueToEncrypt.CreateSha1(); //Assert Assert.That(actualHash, Is.EqualTo(expectedHash)); } diff --git a/Piwik.Tracker/CryptoExtensions.cs b/Piwik.Tracker/CryptoExtensions.cs index 36dab0a..d8bba12 100644 --- a/Piwik.Tracker/CryptoExtensions.cs +++ b/Piwik.Tracker/CryptoExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Security.Cryptography; +using System.Security.Cryptography; using System.Text; namespace Piwik.Tracker @@ -10,51 +9,21 @@ internal static class CryptoExtensions /// Creates a sha1 hash from given . /// /// The value to encrypt. - /// if set to true resulting hash will be formated as hexadecimal string. /// - public static string CreateSha1(this string valueToEncrypt, bool hashAsHexadecimal) + public static string CreateSha1(this string valueToEncrypt) { using (var provider = new SHA1CryptoServiceProvider()) { var bytes = Encoding.UTF8.GetBytes(valueToEncrypt); var encodedBytes = provider.ComputeHash(bytes); - if (hashAsHexadecimal) + var sb = new StringBuilder(); + foreach (byte b in encodedBytes) { - return GetHexStringFromBytes(encodedBytes); + var hex = b.ToString("x2"); + sb.Append(hex); } - return BitConverter.ToString(encodedBytes); + return sb.ToString(); } } - - /// - /// Creates the a MD5 hash from given . - /// - /// The value to encrypt. - internal static string CreateMd5(this string valueToEncrypt) - { - using (var provider = new MD5CryptoServiceProvider()) - { - var bytes = Encoding.UTF8.GetBytes(valueToEncrypt); - var encodedBytes = provider.ComputeHash(bytes); - var hash = BitConverter.ToString(encodedBytes); - return hash.Replace("-", ""); - } - } - - /// - /// Gets the hexadecimal string from bytes. - /// - /// The bytes. - /// - private static string GetHexStringFromBytes(byte[] bytes) - { - var sb = new StringBuilder(); - foreach (byte b in bytes) - { - var hex = b.ToString("x2"); - sb.Append(hex); - } - return sb.ToString(); - } } } \ No newline at end of file diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index 76cc9b3..6209ed4 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -431,7 +431,7 @@ public void ClearCustomTrackingParameters() /// public void SetNewVisitorId() { - _randomVisitorId = Guid.NewGuid().ToString().CreateMd5().Substring(0, LengthVisitorId).ToLower(); + _randomVisitorId = Guid.NewGuid().ToString().CreateSha1().Substring(0, LengthVisitorId).ToLower(); _userId = null; _forcedVisitorId = null; _cookieVisitorId = null; @@ -578,7 +578,7 @@ protected string GetCookieName(string cookieName) ? GetCurrentHost() : _configCookieDomain) + _configCookiePath; - var hash = cookieDomain.CreateSha1(hashAsHexadecimal: true).Substring(0, 4); + var hash = cookieDomain.CreateSha1().Substring(0, 4); return FirstPartyCookiesPrefix + cookieName + "." + IdSite + "." + hash; } @@ -1164,7 +1164,7 @@ public void SetUserId(string userId) /// public static string GetUserIdHashed(string id) { - var hash = id.CreateSha1(hashAsHexadecimal: false); + var hash = id.CreateSha1(); return hash.Substring(0, 16); } From e98d5bc507cbe2e0f3399fe28a5fe1c829a95a72 Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Fri, 14 Apr 2017 11:38:14 +0200 Subject: [PATCH 5/6] sha1 : added overload for byte array renaming CreateSha1 -> ToSha1 --- Piwik.Tracker.Tests/CryptoExtensionsTests.cs | 4 +-- Piwik.Tracker/CryptoExtensions.cs | 26 +++++++++++++++++--- Piwik.Tracker/PiwikTracker.cs | 8 +++--- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs index 63b3173..032119a 100644 --- a/Piwik.Tracker.Tests/CryptoExtensionsTests.cs +++ b/Piwik.Tracker.Tests/CryptoExtensionsTests.cs @@ -12,10 +12,10 @@ internal class CryptoExtensionsTests [TestCase("1-2-3-45-6", "5c13bf8b7ff1d43869a7b4246bef897f9499833b")] [TestCase("öüüä%&&", "c24eb4685cd57f32098b33066b5b08b31e378981")] [TestCase("+- fdgsdgafdgffdsfddgdgdfdfgdfhdghdfghdgfhgfdgar^^°gfra7685&%§$\"$§&(=)(&=,// \\", "bde6cf181dd5bc0ef11342d5c6a4e81a934d9cb8")] - public void CreateSha1_WhenHashMustBeHexadecimal_RegressionTests(string valueToEncrypt, string expectedHash) + public void ToSha1_RegressionTests(string valueToEncrypt, string expectedHash) { //Act - var actualHash = valueToEncrypt.CreateSha1(); + var actualHash = valueToEncrypt.ToSha1(); //Assert Assert.That(actualHash, Is.EqualTo(expectedHash)); } diff --git a/Piwik.Tracker/CryptoExtensions.cs b/Piwik.Tracker/CryptoExtensions.cs index d8bba12..87dd984 100644 --- a/Piwik.Tracker/CryptoExtensions.cs +++ b/Piwik.Tracker/CryptoExtensions.cs @@ -1,4 +1,5 @@ -using System.Security.Cryptography; +using System; +using System.Security.Cryptography; using System.Text; namespace Piwik.Tracker @@ -10,12 +11,29 @@ internal static class CryptoExtensions /// /// The value to encrypt. /// - public static string CreateSha1(this string valueToEncrypt) + public static string ToSha1(this string valueToEncrypt) { + if (valueToEncrypt == null) + { + throw new ArgumentNullException(nameof(valueToEncrypt)); + } + return Encoding.UTF8.GetBytes(valueToEncrypt).ToSha1(); + } + + /// + /// Creates a sha1 hash from given . + /// + /// The value to encrypt. + /// + public static string ToSha1(this byte[] valueToEncrypt) + { + if (valueToEncrypt == null) + { + throw new ArgumentNullException(nameof(valueToEncrypt)); + } using (var provider = new SHA1CryptoServiceProvider()) { - var bytes = Encoding.UTF8.GetBytes(valueToEncrypt); - var encodedBytes = provider.ComputeHash(bytes); + var encodedBytes = provider.ComputeHash(valueToEncrypt); var sb = new StringBuilder(); foreach (byte b in encodedBytes) { diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index 6209ed4..9f502e3 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -17,8 +17,6 @@ namespace Piwik.Tracker using System.Linq; using System.Net; using System.Globalization; - using System.Text; - using System.Security.Cryptography; using System.Web; using System.Web.Script.Serialization; using System.Text.RegularExpressions; @@ -431,7 +429,7 @@ public void ClearCustomTrackingParameters() /// public void SetNewVisitorId() { - _randomVisitorId = Guid.NewGuid().ToString().CreateSha1().Substring(0, LengthVisitorId).ToLower(); + _randomVisitorId = Guid.NewGuid().ToByteArray().ToSha1().Substring(0, LengthVisitorId).ToLower(); _userId = null; _forcedVisitorId = null; _cookieVisitorId = null; @@ -578,7 +576,7 @@ protected string GetCookieName(string cookieName) ? GetCurrentHost() : _configCookieDomain) + _configCookiePath; - var hash = cookieDomain.CreateSha1().Substring(0, 4); + var hash = cookieDomain.ToSha1().Substring(0, 4); return FirstPartyCookiesPrefix + cookieName + "." + IdSite + "." + hash; } @@ -1164,7 +1162,7 @@ public void SetUserId(string userId) /// public static string GetUserIdHashed(string id) { - var hash = id.CreateSha1(); + var hash = (id ?? string.Empty).ToSha1(); return hash.Substring(0, 16); } From d1dc50d4c15febd03ffd7287d4047f9ada5e9675 Mon Sep 17 00:00:00 2001 From: "p.bruch" Date: Mon, 17 Apr 2017 16:08:05 +0200 Subject: [PATCH 6/6] removed obsolete ToLower ("x2" formats as hex lowercase!) --- Piwik.Tracker/PiwikTracker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Piwik.Tracker/PiwikTracker.cs b/Piwik.Tracker/PiwikTracker.cs index 9f502e3..5ebe865 100644 --- a/Piwik.Tracker/PiwikTracker.cs +++ b/Piwik.Tracker/PiwikTracker.cs @@ -429,7 +429,7 @@ public void ClearCustomTrackingParameters() /// public void SetNewVisitorId() { - _randomVisitorId = Guid.NewGuid().ToByteArray().ToSha1().Substring(0, LengthVisitorId).ToLower(); + _randomVisitorId = Guid.NewGuid().ToByteArray().ToSha1().Substring(0, LengthVisitorId); _userId = null; _forcedVisitorId = null; _cookieVisitorId = null;