-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
MachineKeyProtectedData.cs
99 lines (84 loc) · 3.53 KB
/
MachineKeyProtectedData.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using Microsoft.AspNet.SignalR.Infrastructure;
namespace Microsoft.AspNet.SignalR.SystemWeb.Infrastructure
{
public class MachineKeyProtectedData : IProtectedData
{
public string Protect(string data, string purpose)
{
byte[] unprotectedBytes = Encoding.UTF8.GetBytes(data);
return MachineKeyProtectedData40.Protect(unprotectedBytes);
}
public string Unprotect(string protectedValue, string purpose)
{
byte[] unprotectedBytes = MachineKeyProtectedData40.Unprotect(protectedValue);
return Encoding.UTF8.GetString(unprotectedBytes);
}
private static class MachineKeyProtectedData40
{
private const uint MagicHeader = 0x855d4ec9;
public static string Protect(byte[] data)
{
byte[] dataWithHeader = new byte[data.Length + 4];
Buffer.BlockCopy(data, 0, dataWithHeader, 4, data.Length);
unchecked
{
dataWithHeader[0] = (byte)(MagicHeader >> 24);
dataWithHeader[1] = (byte)(MagicHeader >> 16);
dataWithHeader[2] = (byte)(MagicHeader >> 8);
dataWithHeader[3] = (byte)(MagicHeader);
}
string hex = MachineKey.Encode(dataWithHeader, MachineKeyProtection.All);
return HexToBase64(hex);
}
public static byte[] Unprotect(string protectedData)
{
string hex = Base64ToHex(protectedData);
byte[] dataWithHeader = MachineKey.Decode(hex, MachineKeyProtection.All);
if (dataWithHeader == null || dataWithHeader.Length < 4 || (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(dataWithHeader, 0)) != MagicHeader)
{
// the decoded data is blank or doesn't begin with the magic header
return null;
}
byte[] retVal = new byte[dataWithHeader.Length - 4];
Buffer.BlockCopy(dataWithHeader, 4, retVal, 0, retVal.Length);
return retVal;
}
// String transformation helpers
internal static string Base64ToHex(string base64)
{
StringBuilder builder = new StringBuilder((int)(base64.Length * 1.5));
foreach (byte b in HttpServerUtility.UrlTokenDecode(base64))
{
builder.Append(HexDigit(b >> 4));
builder.Append(HexDigit(b & 0x0F));
}
string result = builder.ToString();
return result;
}
private static char HexDigit(int value)
{
return (char)(value > 9 ? value + '7' : value + '0');
}
private static int HexValue(char digit)
{
return digit > '9' ? digit - '7' : digit - '0';
}
internal static string HexToBase64(string hex)
{
int size = hex.Length / 2;
byte[] bytes = new byte[size];
for (int idx = 0; idx < size; idx++)
{
bytes[idx] = (byte)((HexValue(hex[idx * 2]) << 4) + HexValue(hex[(idx * 2) + 1]));
}
string result = HttpServerUtility.UrlTokenEncode(bytes);
return result;
}
}
}
}