Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit

http://issues.umbraco.org/issue/U4-1455
This commit is contained in:
pcw@pcw-PC.shout.local
2013-01-15 20:40:28 +00:00
parent 5458c9a310
commit ac5142443a
4 changed files with 73 additions and 13 deletions

View File

@@ -23,22 +23,60 @@ namespace Umbraco.Core
/// Encrypt the string using the MachineKey in medium trust
/// </summary>
/// <param name="toEncrypt"></param>
/// <param name="value">The string value to be encrypted.</param>
/// <returns></returns>
public static string EncryptWithMachineKey(this string toEncrypt)
public static string EncryptWithMachineKey(this string value)
{
var output = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(0, "temp", DateTime.Now, DateTime.MaxValue, false, toEncrypt));
return output;
if (value == null)
return null;
string valueToEncrypt = value;
List<string> parts = new List<string>();
const int EncrpytBlockSize = 500;
while (valueToEncrypt.Length > EncrpytBlockSize)
{
parts.Add(valueToEncrypt.Substring(0, EncrpytBlockSize));
valueToEncrypt = valueToEncrypt.Remove(0, EncrpytBlockSize);
}
if (valueToEncrypt.Length > 0)
{
parts.Add(valueToEncrypt);
}
StringBuilder encrpytedValue = new StringBuilder();
foreach (var part in parts)
{
var encrpytedBlock = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(0, string.Empty, DateTime.Now, DateTime.MaxValue, false, part));
encrpytedValue.AppendLine(encrpytedBlock);
}
return encrpytedValue.ToString().TrimEnd();
}
/// <summary>
/// Decrypt the encrypted string using the Machine key in medium trust
/// </summary>
/// <param name="encrypted"></param>
/// <param name="value">The string value to be decrypted</param>
/// <returns></returns>
public static string DecryptWithMachineKey(this string encrypted)
public static string DecryptWithMachineKey(this string value)
{
var output = FormsAuthentication.Decrypt(encrypted);
return output.UserData;
if (value == null)
return null;
string[] parts = value.Split('\n');
StringBuilder decryptedValue = new StringBuilder();
foreach (var part in parts)
{
decryptedValue.Append(FormsAuthentication.Decrypt(part.TrimEnd()).UserData);
}
return decryptedValue.ToString();
}
//this is from SqlMetal and just makes it a bit of fun to allow pluralisation

View File

@@ -11,7 +11,10 @@ namespace Umbraco.Tests
public class StringExtensionsTests
{
[TestCase("This is a string to encrypt")]
[TestCase("This is a string to encrypt")]
[TestCase("This is a string to encrypt\nThis is a second line")]
[TestCase(" White space is preserved ")]
[TestCase("\nWhite space is preserved\n")]
public void Encrypt_And_Decrypt(string input)
{
var encrypted = input.EncryptWithMachineKey();
@@ -20,6 +23,25 @@ namespace Umbraco.Tests
Assert.AreEqual(input, decrypted);
}
[Test()]
public void Encrypt_And_Decrypt_Long_Value()
{
// Generate a really long string
char[] chars = { 'a', 'b', 'c', '1', '2', '3', '\n' };
string valueToTest = string.Empty;
// Create a string 7035 chars long
for (int i = 0; i < 1005; i++)
for (int j = 0; j < chars.Length; j++)
valueToTest += chars[j].ToString();
var encrypted = valueToTest.ToString().EncryptWithMachineKey();
var decrypted = encrypted.DecryptWithMachineKey();
Assert.AreNotEqual(valueToTest, encrypted);
Assert.AreEqual(valueToTest, decrypted);
}
[TestCase("Hello this is my string", " string", "Hello this is my")]
[TestCase("Hello this is my string strung", " string", "Hello this is my string strung")]
[TestCase("Hello this is my string string", " string", "Hello this is my")]

View File

@@ -119,7 +119,7 @@ namespace Umbraco.Web
if (!string.IsNullOrWhiteSpace(surfaceRouteParams))
{
_base64String = Convert.ToBase64String(Encoding.UTF8.GetBytes(surfaceRouteParams));
_encryptedString = surfaceRouteParams.EncryptWithMachineKey();
}
_textWriter = viewContext.Writer;
@@ -127,7 +127,7 @@ namespace Umbraco.Web
private bool _disposed;
private readonly string _base64String;
private readonly string _encryptedString;
private readonly TextWriter _textWriter;
protected override void Dispose(bool disposing)
@@ -137,7 +137,7 @@ namespace Umbraco.Web
this._disposed = true;
//write out the hidden surface form routes
_textWriter.Write("<input name='uformpostroutevals' type='hidden' value='" + _base64String + "' />");
_textWriter.Write("<input name='uformpostroutevals' type='hidden' value='" + _encryptedString + "' />");
base.Dispose(disposing);
}

View File

@@ -115,8 +115,8 @@ namespace Umbraco.Web.Mvc
return null;
var encodedVal = requestContext.HttpContext.Request["uformpostroutevals"];
var decodedString = Encoding.UTF8.GetString(Convert.FromBase64String(encodedVal));
var parsedQueryString = HttpUtility.ParseQueryString(decodedString);
var decryptedString = encodedVal.DecryptWithMachineKey();
var parsedQueryString = HttpUtility.ParseQueryString(decryptedString);
var decodedParts = new Dictionary<string, string>();