Skip to content

Instantly share code, notes, and snippets.

@FennyFatal
Last active August 1, 2017 05:29
Show Gist options
  • Save FennyFatal/c44a7ec0dcf2c0789ae8362ca164a588 to your computer and use it in GitHub Desktop.
Save FennyFatal/c44a7ec0dcf2c0789ae8362ca164a588 to your computer and use it in GitHub Desktop.
static void Decrypt(string backup_file)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
using (System.IO.FileStream f = System.IO.File.OpenRead(backup_file))
{
if ("ANDROID BACKUP" != readString(f))
return;
Console.WriteLine("Version:" + readString(f));
bool iscompressed = "1" == readString(f);
string crypto = readString(f);
Stream stream;
if ("none" != crypto)
{
aesEncryption.KeySize = Int32.Parse(crypto.Replace("AES-", ""));
aesEncryption.Mode = CipherMode.CBC;
aesEncryption.Padding = PaddingMode.PKCS7;
string UserSaltHex;
Console.WriteLine(UserSaltHex = readString(f));
string ckSaltHex;
Console.WriteLine(ckSaltHex = readString(f));
int rounds = Int32.Parse(readString(f));
string userIvHex;
Console.WriteLine(userIvHex = readString(f));
string masterKeyBlobHex;
Console.WriteLine(masterKeyBlobHex = readString(f));
byte[] key = new Rfc2898DeriveBytes(getPassword(), StringToByteArray(UserSaltHex), rounds).GetBytes(32);
byte[] IV = StringToByteArray(userIvHex);
byte[] mkCipher = StringToByteArray(masterKeyBlobHex);
byte[] mkBlob = aesEncryption.CreateDecryptor(key, IV).TransformFinalBlock(mkCipher, 0, mkCipher.Length);
int offset = 0;
int len = mkBlob[offset++];
IV = mkBlob.Skip(offset).Take(len).ToArray();
offset += len;
len = mkBlob[offset++];
byte[] mk = mkBlob.Skip(offset).Take(len).ToArray();
offset += len;
len = mkBlob[offset++];
byte[] mkChecksum = mkBlob.Skip(offset).Take(len).ToArray();
byte[] keyChecksum = new Rfc2898DeriveBytes(ByteArrayToString(mk), StringToByteArray(ckSaltHex), rounds).GetBytes(32);
aesEncryption.IV = IV;
var crypter = aesEncryption.CreateDecryptor(mk, IV);
CryptoStream cryptostream = new CryptoStream(f, crypter, CryptoStreamMode.Read);
if (iscompressed)
{
cryptostream.ReadByte();
cryptostream.ReadByte();
}
stream = (iscompressed ?
new DeflateStream(cryptostream, CompressionMode.Decompress)
: (Stream)cryptostream);
}
else
{
stream = f;
}
byte[] buffer = new byte[1024];
int count;
var outfile = File.OpenWrite("out.tar");
while ((count = stream.Read(buffer, 0, 1024)) > 0)
outfile.Write(buffer, 0, count);
//Console.WriteLine(BitConverter.ToString(buffer, 0, count));
}
}
private static string getPassword()
{
StringBuilder s = new StringBuilder();
Console.Write("Password: ");
ConsoleKeyInfo key;
while( (key = Console.ReadKey()).Key != ConsoleKey.Enter )
{
if (key.Key == ConsoleKey.Backspace)
{
if (s.Length > 0)
s.Remove(s.Length - 1, 1);
continue;
}
s.Append(key.KeyChar);
}
return s.ToString();
}
static string ByteArrayToString(byte[] bytes)
{
string result = string.Empty;
foreach (byte b in bytes)
{
result += (char)b;
}
return result;
}
static string readString(FileStream f)
{
string line = String.Empty;
int character;
while ((character = f.ReadByte()) > 0)
{
if (character == '\n')
break;
line += (char)character;
}
return line;
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment