|
using System; |
|
using System.IO; |
|
using System.Security.Cryptography; |
|
using System.Text; |
|
|
|
namespace Decrypt_AuthenticationTicket |
|
{ |
|
class Program |
|
{ |
|
const int SHA1_KEY_SIZE = 64; |
|
const int SHA1_HASH_SIZE = 20; |
|
|
|
static SymmetricAlgorithm DecryptAlgorithm { get; } |
|
static int _IVLengthDecryption { get; } |
|
|
|
static string validationKey_sha1 = ""; |
|
static string decryptionKey_aes = ""; |
|
|
|
|
|
static Program() |
|
{ |
|
DecryptAlgorithm = System.Security.Cryptography.Aes.Create(); |
|
DecryptAlgorithm.Key = HexToBinary(decryptionKey_aes); |
|
|
|
DecryptAlgorithm.GenerateIV(); |
|
DecryptAlgorithm.IV = new byte[DecryptAlgorithm.IV.Length]; |
|
_IVLengthDecryption = (DecryptAlgorithm.KeySize / 8) + (((DecryptAlgorithm.KeySize & 7) != 0) ? 1 : 0); |
|
} |
|
|
|
static void Main(string[] args) |
|
{ |
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
|
|
|
var encryptedTicket = ""; |
|
|
|
for (var i = 0; i < 1; i++) |
|
{ |
|
|
|
var bBlob = HexToBinary(encryptedTicket); |
|
var buf = GetUnHashedData(bBlob); |
|
|
|
byte[] paddedData; |
|
|
|
using (var ms = new MemoryStream()) |
|
using (var cryptoTransform = DecryptAlgorithm.CreateDecryptor()) |
|
using (var cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) |
|
{ |
|
|
|
cs.Write(buf, 0, buf.Length); |
|
cs.FlushFinalBlock(); |
|
paddedData = ms.ToArray(); |
|
} |
|
|
|
// strip IV |
|
var bDataLength = paddedData.Length - _IVLengthDecryption; |
|
var bData = new byte[bDataLength]; |
|
Buffer.BlockCopy(paddedData, _IVLengthDecryption, bData, 0, bDataLength); |
|
|
|
//var ticketLength -= MachineKeySection.HashSize; |
|
//var ticket = FormsAuthenticationTicketSerializer.Deserializa(bBlob, ticketLength) |
|
using (var blobStream = new MemoryStream(bData)) |
|
{ |
|
using (var reader = new SerializingBinaryReader(blobStream)) |
|
{ |
|
var formatVersion = reader.ReadByte(); |
|
|
|
var version = reader.ReadByte(); |
|
|
|
var utcTicks = reader.ReadInt64(); |
|
var created = new DateTime(utcTicks, DateTimeKind.Utc).ToLocalTime(); |
|
|
|
var spacer = reader.ReadByte(); |
|
|
|
var expireDateTicks = reader.ReadInt64(); |
|
var expire = new DateTime(expireDateTicks, DateTimeKind.Utc).ToLocalTime(); |
|
|
|
var persistenceField = reader.ReadByte(); |
|
|
|
|
|
var name = reader.ReadString(); |
|
Console.WriteLine(name); |
|
|
|
var userData = reader.ReadString(); |
|
|
|
var path = reader.ReadString(); |
|
|
|
var footer = reader.ReadByte(); |
|
} |
|
|
|
} |
|
} |
|
} |
|
|
|
private sealed class SerializingBinaryReader : BinaryReader |
|
{ |
|
public SerializingBinaryReader(Stream input) |
|
: base(input) |
|
{ |
|
} |
|
|
|
public override string ReadString() |
|
{ |
|
int charCount = Read7BitEncodedInt(); |
|
byte[] bytes = ReadBytes(charCount * 2); |
|
|
|
char[] chars = new char[charCount]; |
|
for (int i = 0; i < chars.Length; i++) |
|
{ |
|
chars[i] = (char)(bytes[2 * i] | (bytes[2 * i + 1] << 8)); |
|
} |
|
|
|
return new String(chars); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
static byte[] GetUnHashedData(byte[] bufHashed) |
|
{ |
|
if (!VerifyHashData(bufHashed)) |
|
{ |
|
return null; |
|
} |
|
|
|
|
|
var buf2 = new byte[bufHashed.Length - SHA1_HASH_SIZE]; |
|
Buffer.BlockCopy(bufHashed, 0, buf2, 0, buf2.Length); |
|
return buf2; |
|
} |
|
|
|
static bool VerifyHashData(byte[] bufHashed) |
|
{ |
|
var hasher = new HMACSHA1(HexToBinary(validationKey_sha1)); |
|
var bMac = hasher.ComputeHash(bufHashed, 0, bufHashed.Length - SHA1_HASH_SIZE); |
|
|
|
var lastPos = bufHashed.Length - SHA1_HASH_SIZE; |
|
|
|
var hashCheckFailed = false; |
|
for (var iter = 0; iter < SHA1_HASH_SIZE; iter++) |
|
{ |
|
if (bMac[iter] != bufHashed[lastPos + iter]) |
|
{ |
|
hashCheckFailed = true; |
|
} |
|
} |
|
|
|
return !hashCheckFailed; |
|
} |
|
|
|
static int HexToInt(char h) |
|
{ |
|
return |
|
(h >= '0' && h <= '9') ? h - '0' |
|
: (h >= 'a' && h <= 'f') ? h - 'a' + 10 |
|
: (h >= 'A' && h <= 'F') ? h - 'A' + 10 |
|
: -1 |
|
; |
|
} |
|
|
|
static byte[] HexToBinary(string data) |
|
{ |
|
if (data == null || data.Length % 2 != 0) |
|
{ |
|
return null; |
|
} |
|
|
|
var binary = new byte[data.Length / 2]; |
|
|
|
for (int i = 0; i < binary.Length; i++) |
|
{ |
|
int highNibble = HexToInt(data[2 * i]); |
|
int lowNibble = HexToInt(data[2 * i + 1]); |
|
|
|
if (highNibble == -1 || lowNibble == -1) |
|
{ |
|
return null; |
|
} |
|
|
|
binary[i] = (byte)((highNibble << 4) | lowNibble); |
|
} |
|
|
|
return binary; |
|
|
|
} |
|
} |
|
} |