using System.Web;
using System.Web.Configuration;
using System.Web.Util;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
namespace System.Web.Security
{
return MachineKeySectionUtils.GetHexString (result);
}
+
+#if NET_4_5
+ public static byte[] Protect (byte[] userData, params string[] purposes)
+ {
+ if (userData == null)
+ throw new ArgumentNullException ("userData");
+
+ foreach (var purpose in purposes)
+ {
+ if (string.IsNullOrWhiteSpace (purpose))
+ throw new ArgumentException ("all purpose parameters must contain text");
+ }
+
+ var config = WebConfigurationManager.GetWebApplicationSection ("system.web/machineKey") as MachineKeySection;
+ var purposeJoined = string.Join (";", purposes);
+ var purposeBytes = GetHashed (purposeJoined);
+ var bytes = new byte [userData.Length + purposeBytes.Length];
+ purposeBytes.CopyTo (bytes, 0);
+ userData.CopyTo (bytes, purposeBytes.Length);
+ return MachineKeySectionUtils.Encrypt (config, bytes);
+ }
+
+ public static byte[] Unprotect (byte[] protectedData, params string[] purposes)
+ {
+ if (protectedData == null)
+ throw new ArgumentNullException ("protectedData");
+
+ foreach (var purpose in purposes) {
+ if (string.IsNullOrWhiteSpace (purpose))
+ throw new ArgumentException ("all purpose parameters must contain text");
+ }
+
+ var config = WebConfigurationManager.GetWebApplicationSection ("system.web/machineKey") as MachineKeySection;
+ var purposeJoined = string.Join (";", purposes);
+ var purposeBytes = GetHashed (purposeJoined);
+ var unprotected = MachineKeySectionUtils.Decrypt (config, protectedData);
+
+ for (int i = 0; i < purposeBytes.Length; i++) {
+ if (purposeBytes [i] != unprotected [i])
+ throw new CryptographicException ();
+ }
+
+ var dataLength = unprotected.Length - purposeBytes.Length;
+ var result = new byte [dataLength];
+ Array.Copy (unprotected, purposeBytes.Length, result, 0, dataLength);
+ return result;
+ }
+
+ static byte[] GetHashed (string purposes)
+ {
+ using (var hash = SHA512.Create ()) {
+ var bytes = Encoding.UTF8.GetBytes (purposes);
+ return hash.ComputeHash (bytes, 0, bytes.Length);
+ }
+ }
+#endif
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Security.Cryptography;
+
+
#if NET_4_0
using System;
using System.Text;
// Success
}
}
+
+#if NET_4_5
+ [Test]
+ public void Protect ()
+ {
+ AssertExtensions.Throws<ArgumentNullException> (() =>
+ MachineKey.Protect (null, null),
+ "MachineKey.Protect not throwing an ArgumentNullException");
+
+ AssertExtensions.Throws<ArgumentNullException> (() =>
+ MachineKey.Protect (null, new [] { "test" }),
+ "MachineKey.Protect not throwing an ArgumentNullException");
+
+ var testString = "asfgasd43tqrt4";
+ var validUsages = new [] { "usage1", "usage2" };
+ var oneUsage = new [] { "usage1" };
+ var invalidUsages = new [] { "usage1", "invalidUsage" };
+
+ var plainBytes = Encoding.ASCII.GetBytes (testString);
+ var encryptedBytes = MachineKey.Protect (plainBytes, validUsages);
+ var validDecryptedBytes = MachineKey.Unprotect (encryptedBytes, validUsages);
+
+ Assert.AreEqual (plainBytes, validDecryptedBytes, "Decryption didn't work");
+
+ AssertExtensions.Throws<CryptographicException> (() =>
+ MachineKey.Unprotect (encryptedBytes, invalidUsages),
+ "Purposes not encrypting properly");
+
+ AssertExtensions.Throws<CryptographicException> (() =>
+ MachineKey.Unprotect (encryptedBytes, oneUsage),
+ "Single purpose working when multiple supplied");
+ }
+#endif
}
}
-#endif
\ No newline at end of file
+#endif